Skip to content

[opencode2] Code Mode catalog advertises 'search' but runtime only registers 'tools.$codemode.search' #43624

Closed

Description

@ahosker

Description

When an MCP tool catalog exceeds the inline budget (PARTIAL list), the Code Mode instructions injected into the execute tool description advertise a discovery tool called search:

"Use search to discover exact paths and signatures for additional tools"
search(input: { query, namespace, limit, offset })

But the runtime registers it under the reserved namespace: tools.$codemode.search (packages/codemode/src/tool-runtime.ts — makeSearchTool, reservedNamespace).

Calling tools.search(...) as advertised fails:

Unknown tool 'search'. The tool may have been removed or renamed. Use search to find available tools.

The error's fallback advice points back at the same broken name — circular dead end. Any agent that trusts the catalog instructions hits this.

Steps to reproduce

  1. Configure an MCP server with a large tool catalog (enough to trigger a PARTIAL inline list, e.g. "9 tools, 7 shown").
  2. Instruct the agent to use a tool omitted from the partial list (e.g. via tools.search(...) as the catalog says).
  3. Observe Unknown tool 'search' from the Code Mode runtime.

Expected behavior

Either the catalog instructions should advertise tools.$codemode.search (its actual registered path), or the runtime should also expose it as tools.search.

Environment

  • OpenCode 2.x (beta), Code Mode enabled (default)

Activity

  1. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

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

    • codemode: Executor nested tool search fails in TUI #40611: Same "Unknown tool 'search'" error in Code Mode — Executor's nested tools.search() resolves against OpenCode's outer Code Mode catalog where it doesn't exist, producing the same circular dead-end error. The root cause framing differs slightly (routing vs. advertised name mismatch), but both point to the same naming inconsistency between what the catalog describes and what the runtime registers.
  2. ahosker commented on Aug 20, 2026

    @ahosker
    ContributorAuthor

    Investigated on v2 (879766aee7) — the core claim does not reproduce as described.

    The catalog instructions advertise search as a global function inside Code Mode code, not as tools.search:

    • packages/core/src/codemode/instructions.ts:15-17 — "Use `search` to discover…", rendering CodeMode.searchSignature
    • searchSignature resolves to a bare search(input: { query, namespace, limit, offset }), with no tools. prefix
    • packages/codemode/src/interpreter/runtime.ts:306 registers search as a reserved interpreter global (SearchFunction), dispatched at runtime.ts:2001 via ToolRuntime.search (interpreter/execute.ts:51)

    Verified directly against the v2 runtime:

    const runtime = CodeMode.make({ tools: { ns: { demo } } })
    await runtime.execute(`return search({ query: "demo" })`)   // ok: true
    await runtime.execute(`return tools.search({ query: "demo" })`) // Unknown tool 'search' (expected — not advertised)

    Invalid assumptions in the report:

    • There is no tools.$codemode.search registration and no reservedNamespace symbol anywhere in packages/codemode/src (or anywhere on the v2 tree). The cited makeSearchTool is internal wiring for the interpreter-global search, not a namespaced tool.
    • Nothing in the codebase advertises tools.search; git grep 'tools.search' matches only the internal interpreter wiring.
    • The Unknown tool 'search' error only occurs if an agent chooses tools.search despite the instructions showing the bare-global form.

    Remaining valid kernel: the error-message advice at packages/codemode/src/tool-runtime.ts:473 — "Use search to find available tools" — is ambiguous; an agent that just failed calling tools.search may not infer it means the bare global. Suggested fix for maintainers: reword the hints in tool-runtime.ts to e.g. "Call the global search({ query }) function to find available tools." (and similarly for the stale-signature hint at line ~540), plus update the two expectations in packages/codemode/test/tool-paths.test.ts.

  3. opencode-agent commented on Aug 20, 2026

    @opencode-agent
    Contributor

    Thanks for the report. This appears to be based on the dev branch rather than the current v2 implementation.

    On v2, the catalog intentionally advertises bare search(...):

    There is no reservedNamespace or tools.$codemode.search registration in the current v2 tree. tools.search(...) is therefore not the advertised call—the correct Code Mode call is the global search(...).

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions