Skip to content

agent: frontmatter description starting with '[' silently drops the agent (AgentNotFoundError) #54200

Closed

Description

@anthonyplews

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 plugins entries in opencode.json

Reproduction

  1. Create .opencode/agent/zztest.md:

    ---
    description: [Test] unquoted description
    mode: subagent
    ---
    
    Reply with exactly: OK
  2. Launch it with a fresh/private server:

    opencode run --standalone --agent zztest --model deepseek/deepseek-flash "go"
  3. Observe: Error: Agent not found: "zztest".

  4. GET /api/agent?location[directory]=<project> omits zztest entirely — no
    error, no warning.

  5. Quote the same value (description: "[Test] unquoted description") and repeat
    step 2 → the agent loads and replies OK.

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 returns QUOTED_OK

Expected Behavior

Either:

An invalid YAML scalar should not make the agent disappear silently.

Actual Behavior

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

Activity

  1. opencode-agent commented on Oct 9, 2026

    @opencode-agent
    Contributor

    Thanks for the clear report and the control case. I could reproduce this on 2.0.26.

    What I did:

    • Created two agents under .opencode/agent/: one with description: [Test] unquoted description and one with the same value in quotes.
    • opencode run --standalone --agent zzbracket ... fails with Error: Agent not found: "zzbracket". Even with --print-logs --log-level debug, the only related log line is Failed to drain Session ... AgentNotFoundError. Nothing mentions the frontmatter.
    • The quoted agent is found. In my sandbox it then stops only because no model provider is configured.

    I also checked the latest v2 branch (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 description value is the workaround, as you found.

    Related: #45876 (no warning when agent frontmatter is invalid YAML) and #53909 (unquoted : in description).

    Reproduction script (repro.sh)
    #!/usr/bin/env bash
    # Repro for #54200: agent frontmatter description starting with '[' silently drops the agent.
    # Usage: OPENCODE="opencode" bash repro.sh   (or set OPENCODE to a source-run command)
    OPENCODE=${OPENCODE:-opencode}
    P=$(mktemp -d /tmp/opencode/p54200.XXXX)
    mkdir -p "$P/.opencode/agent"
    cat > "$P/.opencode/agent/zzbracket.md" <<'MD'
    ---
    description: [Test] unquoted description
    mode: subagent
    ---
    
    Reply with exactly: OK
    MD
    cat > "$P/.opencode/agent/zzquoted.md" <<'MD'
    ---
    description: "[Test] quoted description"
    mode: subagent
    ---
    
    Reply with exactly: OK
    MD
    cd "$P"
    $OPENCODE --version
    echo "== unquoted [ =="
    timeout 60 $OPENCODE run --standalone --agent zzbracket --model fake/fake "go" 2>&1 | tail -5
    echo "== quoted =="
    timeout 60 $OPENCODE run --standalone --agent zzquoted --model fake/fake "go" 2>&1 | tail -5

    Run it: bash repro.sh

  2. argszero commented on Oct 9, 2026

    @argszero
    Contributor

    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 in packages/core/src/config/markdown.ts:sanitize runs. 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. Since sanitize only runs after a strict parse failure, valid flow sequences elsewhere in the file are unaffected.

  3. argszero commented on Oct 10, 2026

    @argszero
    Contributor

    Implemented in #54343.

    sanitize in packages/core/src/config/markdown.ts now 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 [unclosed is still a loud syntax error rather than a silently quoted string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions