Repository navigation
serve: a config load error is cached per project instance — fixing/deleting the offending command file does not clear it until /global/dispose #50906
Description
Description
On a long-lived opencode serve, configuration is loaded once per project instance and cached for the process lifetime. When that initial load fails validation, the failure is cached too: fixing (or even deleting) the offending file does not clear it. Every subsequent opencode attach --dir <project> keeps failing with the same error until /global/dispose is called or the server is restarted, with no in-product hint that this is stale state.
The concrete trigger I hit: a command file whose frontmatter has an empty value:
---
description:
agent: copilot
---An empty YAML value parses to null. The command schema (packages/core/src/v1/config/command.ts) declares description: Schema.optional(Schema.String) = string | undefined, so null fails:
Configuration is invalid at /path/.opencode/commands/<name>.md: SchemaError: Expected string | undefined, got null
at ["description"]
The user then fills in a description (or removes the file), retries, and gets the identical error — the server is still serving the cached failed load.
Steps to reproduce
- Start a long-lived server in a scratch dir:
opencode serve --port 4096 - In a project, create
.opencode/commands/foo.md:--- description: agent: copilot --- body
opencode attach http://127.0.0.1:4096 --dir <project>→SchemaError: Expected string | undefined, got null at ["description"]- Edit the file to give
descriptiona value — or delete the file entirely. opencode attach http://127.0.0.1:4096 --dir <project>again → the same error, for the deleted file path.POST http://127.0.0.1:4096/global/dispose(or a freshopencode serveon another port, same--dir) → the project loads cleanly.
Actual
- The parse failure is cached in the per-project instance (
InstanceStore); config is not re-read on file change. - A transient authoring mistake becomes a sticky, unrecoverable-looking startup failure.
- The error message names the file but gives no hint that the file has already been fixed or that a reload is required.
Expected
Any of:
- The instance is invalidated when a config/command/agent file changes (or at least when a previous load failed), so the next use re-reads from disk; or
- A failed config load is not cached permanently; or
- At minimum, the error surfaces an explicit remediation hint (e.g. "config is cached; run
/global/dispose/ reload to retry").
Separately and trivially: since the field is optional, coercing an empty frontmatter value (null) to undefined for description/agent/model would prevent the most common form of this trap.
Root cause (v1.18.25)
packages/opencode/src/config/command.ts—ConfigCommand.load()throwsInvalidErroron the first command that fails schema decode.packages/core/src/v1/config/command.ts—description: Schema.optional(Schema.String); empty YAML →null.packages/core/src/config/markdown.ts—gray-matteryieldsnullfor an empty value.- Config is loaded once per instance in
InstanceStore; the failed state persists untilPOST /global/dispose(Server.disposeAllInstances…).
Impact
Any persistent serve deployment (headless/multi-attach) is affected. A single bad frontmatter edit — including one made by another agent/build step — wedges the project's config until someone knows the undocumented dispose endpoint. This is the same class of "rewrite a config file under a live server and state never recovers" as #46245 (agents), but here it manifests as a hard validation error rather than empty responses.
Related
- serve: rewriting an agent file under a live server poisons sessions — asks return empty text (200 OK, zero tokens) until restart #46245 — rewriting an agent file under a live server poisons sessions until restart (same cached-config root cause)
- skills: project .agents created after startup is not discovered until config reload #42478 — project
.agentscreated after startup not discovered until reload - Slash skill commands do not reload edited SKILL.md content #49451 — edited
SKILL.mdcontent not reloaded - [FEATURE]: /reload slash command with auto-resume #43454 / [FEATURE]: slash command for reload #6719 / [FEATURE]: Will 2.0 config hot-reload expose an HTTP/SDK trigger for headless
serve? #43698 — hot-reload / reload trigger feature requests
Environment
- OpenCode 1.18.25
- Linux Mint 22.1 (Debian-based), kernel 6.8.0-107
- Long-lived
opencode serve --port 4096+ multipleopencode attach --dir .clients - Plugins:
opencode-notify; local worktree/mcp-daemon/browser-safety plugins
Activity
holny commentedon Sep 23, 2026
I'll take this. Reproduction paths line up with the per-project instance cache in InstanceStore: a config parse failure is stored as the instance's config state, so after the offending file is fixed or deleted nothing re-runs the load and every attach keeps reading the same cached failure.
Plan: make the failed load non-sticky for config — either wait for the location watcher's invalidation to re-attempt the load, or clear the cached failure when the offending path changes/disappears. Both attached and fresh sessions need to see the corrected state without a /global/dispose, and the cache should keep succeeding loads as they are.
I'll also add a regression that seeds a bad config, attaches, fixes the file, and asserts the next attach succeeds.
Fixes #50906
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊