Skip to content

codemode: tool discovery helper documented three ways; only bare search(input) works on 1.18.21 — README's 'never fails' claim is false #45521

Closed

Description

@barrygfox

Summary

Three opencode surfaces describe the Code Mode tool-discovery helper with three
different invocation forms, and on opencode 1.18.21 only one of them works:

Surface Form shown Works on 1.18.21?
Generated execute() scaffold ("## Search" section) search(input: {...}) — bare global ✅ yes (verified)
packages/codemode/README.md + generated "## Workflow"/"## Rules" text tools.$codemode.search({...}) ❌ no — Unknown tool '$codemode.search'.
What a model infers from the catalog's own path convention (tools.<ns>.<tool>) tools.search({...}) ❌ no — Unknown tool 'search'.

Impact: models following either of the two documented namespaced forms hit a hard
UnknownTool failure with no actionable suggestion, and can misdiagnose the
scaffolding as broken rather than mis-invoked.

The README also states the search tool is "always registered … so a speculative
tools.$codemode.search call never fails as an unknown tool"
— that claim is
false on this build (reproduction below).

Environment

  • opencode version: 1.18.21 (Homebrew, release)
  • OS: Darwin 27.0.0 arm64 (macOS)
  • Terminal: iTerm.app (xterm-256color, truecolor)
  • Shell: /bin/zsh
  • Install/channel: release
  • Active plugins: @dietrichgebert/ponytail, @ljw1004/opencode-trace

Reproduction

Deterministic within a single session; each form was tested in its own execute()
sandbox against the same partial catalog (~91 tools across 6 namespaces):

  1. Start a session with Code Mode active and a partial inline catalog.
  2. In one execute() sandbox, run tools.$codemode.search({ query: "jira", limit: 2 })
    — the README's documented form.
    → Unknown tool '$codemode.search'.
  3. In another sandbox, run Object.keys(tools) → lists the 6 MCP namespaces with
    no $codemode namespace present, confirming it is not registered there at all.
  4. In another sandbox, run bare search({ query: "jira add comment", limit: 2 })
    → succeeds immediately, returning exact catalog paths such as
    tools["mcp-atlassian-jira"].jira_add_comment.

Similarly tools.search({ query }) → Unknown tool 'search'.

Expected Behavior

  1. One canonical invocation form should hold everywhere: scaffold, README, and the
    Workflow/Rules guidance baked into every execute() description.
  2. The UnknownTool suggestions for these paths should point at whichever form is
    real (e.g. "use bare search({ query })"), instead of failing circularly —
    notably, upstream tool-runtime.ts already attaches helpful suggestions to
    UnknownTool errors; this build surfaced none for either failed form.
  3. If the intended contract is tools.$codemode.search, then per the README it
    should never raise UnknownTool; if the intended contract is a bare global, the
    README/workflow text should not advertise $codemode.search, and the "never
    fails" sentence needs correcting or version-scoping.

Actual Behavior

  • The generated scaffold on 1.18.21 documents discovery as a bare global
    search(input: {...}), separate from the ## Available tools section whose
    entries are all tools.*.
  • The codemode README (and current dev/v2 source in tool-runtime.ts) document the
    same helper as tools.$codemode.search(...), always registered under a reserved
    namespace, and Object.keys(tools) on other builds reportedly includes
    $codemode.
  • On 1.18.21 neither namespaced form resolves, and Object.keys(tools) shows no
    $codemode; only the bare global exists. Any model following the README or the
    convention it learned from the catalog fails and gets an unhelpful error.

Related but distinct prior reports:

Additional Context

Suggested fix directions (any one suffices):

  1. Register the discovery tool in both places inside the sandbox (alias bare
    search ↔ tools.$codemode.search), so all three documented forms work.
  2. Version-scope/correct the README's "never fails as an unknown tool" claim, or
    restore registration under $codemode.
  3. Make the two failing paths' UnknownTool suggestions name the working form.

Local mitigation on this machine: a version-stamped instruction block in
~/.config/opencode/AGENTS.md documenting that discovery is a bare global on
1.18.21 and everything else lives under tools.*.

Activity

  1. github-actions commented on Aug 27, 2026

    @github-actions
    Contributor

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

    These issues were closed — if the fix didn't land or regressed in 1.18.21, it may be worth linking this report to those for context.

  2. barrygfox commented on Aug 27, 2026

    @barrygfox
    Author

    Bot Update

    Update: I checked #43624, #45349, and #43925. They are useful context, but not duplicates of this report. #45349 and #43925 invoke tools.search(...) and were closed because the V2-facing API is the bare global search(...). #43624 is the closest match, but its maintainers attributed it to a different/dev implementation.

    This report remains distinct: on release 1.18.21, the README and generated Workflow/Rules guidance advertise tools.$codemode.search(...), while the runtime exposes only bare search(...) and no $codemode namespace. That release-specific documentation/runtime divergence, plus the unhelpful UnknownTool response, is the issue being reported.

  3. neriousy commented on Oct 19, 2026

    @neriousy
    Member

    In v2, the README and generated Code Mode instructions consistently document the synchronous bare search(...) function inside execute, and the runtime provides that function. The old guidance advertising tools.$codemode.search and promising that namespace always exists has been removed. To get v2: npm i -g @opencode/cli@latest or curl -fsSL https://opencode.ai/v2/install | bash (desktop: update the app). If you still see this on v2, please open a new issue with the details.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions