Skip to content

commands: unresolvable model in frontmatter silently drops the command #52065

Closed

Description

@51smith

Description

A command .md whose frontmatter carries a model: value that doesn't resolve — e.g. a bare name like opus instead of provider/model — is silently dropped. It never appears in / autocomplete and nothing is logged (no warning at INFO or DEBUG in opencode.log). This bites anyone porting commands from tools that use bare model shorthand: 17 ported commands here, zero appeared, zero feedback. For contrast, other unrecognized frontmatter keys (e.g. effort: high) are silently ignored — only model kills the whole command.

Suggestion: fall back to the session/default model and log a warning naming the file and the rejected value.

Plugins — none

OpenCode version — v2.0.19 (latest channel)

Steps to reproduce

  1. mkdir -p .opencode/commands

  2. Create .opencode/commands/hello.md:

    ---
    description: says hello
    model: opus
    ---
    
    Say hello: $ARGUMENTS
  3. Type / in the TUI (or GET /api/command?location[directory]=<project>) — hello is absent.

  4. Change model: opus to a valid ref (or delete the line) — the command appears immediately, no restart.

Expected: the command loads (ignoring the bad model), or at least a logged warning.

Actual: silent drop; 100% reproducible. (Verified along the way: symlinked command files load fine — the drop is purely the model validation.)

Operating System — macOS (Darwin 25.6.0, arm64)

Terminal — TERM=xterm-256color, COLORTERM=truecolor

Shell — zsh

Activity

  1. github-actions commented on Sep 29, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. 51smith commented on Sep 29, 2026

    @51smith
    Author

    Checked #50849 — same symptom family (silent model-frontmatter drop), but a distinct failure mode:

    Different artifact, different code path, different blast radius — keeping this open for the command case.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the clear report. I could reproduce this on v2.0.19, and it still happens on the latest dev (86ce19d).

    Setup: two otherwise identical project commands in .opencode/commands/. hello-bad.md has model: opus in its frontmatter and hello-ok.md has no model line. Typing /hello in the TUI lists only /hello-ok. The recording and screenshots below show this, and the script below reproduces it.

    The cause seems to be that the command loader checks all the frontmatter at once. When the model value isn't a provider/model reference, the whole file fails and is skipped without a log message. Until this is changed, using a full provider/model value or removing the model: line works around it.

    Related:

    recording.mp4

    Screenshot

    Screenshot

    Reproduction script (drive.ts)
    // Repro for #52065: a command whose frontmatter `model:` is not provider/model
    // (e.g. `model: opus`) is silently missing from `/` autocomplete.
    import { Effect } from "effect"
    import { OpenCodeDriver } from "opencode-drive"
    
    export default OpenCodeDriver.use(
      {
        ...(process.env.OC_DEV ? { opencode: { dev: process.env.OC_DEV } } : {}),
        tui: { recording: true, keypressOverlay: true },
        project: {
          git: true,
          files: {
            // Same command, but with a bare model name: expected to load, is dropped.
            ".opencode/commands/hello-bad.md":
              "---\ndescription: says hello (model: opus)\nmodel: opus\n---\n\nSay hello: $ARGUMENTS\n",
            // Control: identical command without the model line: loads fine.
            ".opencode/commands/hello-ok.md":
              "---\ndescription: says hello (no model)\n---\n\nSay hello: $ARGUMENTS\n",
          },
        },
      },
      ({ ui }) =>
        Effect.gen(function* () {
          yield* Effect.sleep(1500)
          yield* ui.type("/hello")
          yield* ui.waitFor("says hello (no model)")
          yield* Effect.sleep(1500)
          const frame = yield* ui.capture()
          const text = JSON.stringify(frame)
          yield* ui.screenshot("autocomplete")
          const bad = text.includes("hello-bad")
          yield* Effect.log(`hello-ok listed: ${text.includes("hello-ok")}; hello-bad listed: ${bad}`)
          if (!bad) yield* Effect.log("REPRODUCED: command with `model: opus` is missing from / autocomplete")
        }),
    )

    Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.

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