Repository navigation
Description
Summary
In OpenCode 2, an agent Markdown file whose frontmatter description is an
unquoted plain scalar starting with [ (e.g. description: [Team] Does a thing)
is silently dropped from the agent registry. No warning or error is logged, the
agent is missing from GET /api/agent, and any session bound to it later dies
with Session.AgentNotFoundError. The same file loads correctly in OpenCode 1
and as soon as the value is quoted in V2, so this looks like a V1→V2 parser
strictness regression around frontmatter normalization.
Environment
- opencode version: 2.0.26
- OS: Darwin 27.0.0 (darwin arm64)
- Terminal: TERM_PROGRAM=vscode, TERM=xterm-256color, COLORTERM=truecolor
- Shell: /bin/zsh
- Install/channel: latest release
- Active plugins:
- project-local
.opencode/plugins/apstory-sync-agents.ts - global
.config/openchamber/agent-tool(loaded from outside opencode config) - no
pluginsentries inopencode.json
- project-local
Reproduction
-
Create
.opencode/agent/zztest.md:--- description: [Test] unquoted description mode: subagent --- Reply with exactly: OK
-
Launch it with a fresh/private server:
opencode run --standalone --agent zztest --model deepseek/deepseek-flash "go" -
Observe:
Error: Agent not found: "zztest". -
GET /api/agent?location[directory]=<project>omitszztestentirely — no
error, no warning. -
Quote the same value (
description: "[Test] unquoted description") and repeat
step 2 → the agent loads and repliesOK.
This is fully deterministic on a fresh server (not the stale-parse-cache case
from #53909): the unquoted value never loads, the quoted value always does. A
control test with two throwaway agents in the same directory reproduced it:
description: [Test] unquoted description→Agent not found: "zztest-bracket"description: "[Test] quoted description"→ runs and returnsQUOTED_OK
Expected Behavior
Either:
- parse/normalize the value (as the frontmatter parser already does for
descriptions containing an unquoted:per fix(core): bypass gray-matter content cache when parsing frontmatter #51245), or - surface a frontmatter parse error/warning so the user knows the agent was not
loaded.
An invalid YAML scalar should not make the agent disappear silently.
Actual Behavior
-
The agent is dropped from the registry with no diagnostic of any kind.
-
GET /api/agentsimply lacks the entry. -
Sessions using that agent later fail at drain:
level=ERROR message="Failed to drain Session" cause="Session.AgentNotFoundError: Agent not found: \"orchestration-agent\""(and, per Completed session marked failed, work reported lost, when its agent is missing at drain (
Session.AgentNotFoundError) #53500, the session is then marked failed even though earlier work
completed).
The frontmatter value is invalid YAML: a plain scalar cannot begin with [,
which YAML parses as a flow-sequence indicator, so [Test] unquoted description
becomes a sequence plus unexpected trailing scalar. OpenCode 1 loaded these
files; V2 does not.
Additional Context
- Cause is easy to miss because the failure is silent. Since these agents are
generated from a wiki and copied into many projects, one baddescription
prefix takes out most of an agent suite at once. - Related issues: agent: unquoted colon in description silently resolves mode as primary #53909 (unquoted
:indescription, auto-quoted after
fix(core): bypass gray-matter content cache when parsing frontmatter #51245), permission.skill / tools.skill in standalone agent .md frontmatter is parsed but silently ignored at config resolution #41712 (frontmatter parsed but silently ignored), Completed session marked failed, work reported lost, when its agent is missing at drain (Session.AgentNotFoundError) #53500
(AgentNotFoundErrormarked as a failed session at drain), Agent not found for an existing agent while plugins reload after a plugin file changes #54172 (agent
missing while plugins reload). - Workaround: quote any
descriptionvalue that starts with[(or any special
YAML indicator character). - Request: please emit a warning (or reject the file loudly) when agent
frontmatter fails to parse, and consider extending the existing auto-quote
normalization to leading[.
Activity
opencode-agent commentedon Oct 9, 2026
Thanks for the clear report and the control case. I could reproduce this on 2.0.26.
What I did:
.opencode/agent/: one withdescription: [Test] unquoted descriptionand one with the same value in quotes.opencode run --standalone --agent zzbracket ...fails withError: Agent not found: "zzbracket". Even with--print-logs --log-level debug, the only related log line isFailed to drain Session ... AgentNotFoundError. Nothing mentions the frontmatter.I also checked the latest
v2branch (744aa0c). The frontmatter parser there still fails on the unquoted[value and still drops the agent without a warning. The current fallback only fixes values containing an unquoted:(from #51245), so a value starting with[isn't covered. The script below reproduces it.Until this is fixed, quoting the
descriptionvalue is the workaround, as you found.Related: #45876 (no warning when agent frontmatter is invalid YAML) and #53909 (unquoted
:indescription).Reproduction script (repro.sh)
Run it:
bash repro.shargszero commentedon Oct 9, 2026
I'd like to work on this.
The strict YAML parse fails because
[Test]opens a flow sequence and the trailing text makes the document invalid, so the lenient retry inpackages/core/src/config/markdown.ts:sanitizeruns. That fallback only rewrites plain values containing a colon, so this line survives untouched, the second parse throws, and the agent is dropped with no diagnostic.Plan: extend the fallback to quote plain values that open with a YAML indicator (
[,{,*,&,!,%,@, backtick), so they decode as strings when the document is already invalid, and add a test that an unquoted[...]description keeps the agent registered. Sincesanitizeonly runs after a strict parse failure, valid flow sequences elsewhere in the file are unaffected.argszero commentedon Oct 10, 2026
Implemented in #54343.
sanitizeinpackages/core/src/config/markdown.tsnow quotes a plain frontmatter value that opens a flow collection and then continues with text, so the agent is no longer dropped from the registry. The rule is deliberately narrowed to that shape: a bare[a, b]is still read as a list, and an unterminated[unclosedis still a loud syntax error rather than a silently quoted string.