You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[opencode2] Code Mode catalog advertises 'search' but runtime only registers 'tools.$codemode.search' #43624
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
Configure an MCP server with a large tool catalog (enough to trigger a PARTIAL inline list, e.g. "9 tools, 7 shown").
Instruct the agent to use a tool omitted from the partial list (e.g. via tools.search(...) as the catalog says).
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.
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.
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)
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 choosestools.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.
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(...).
Activity
github-actions commentedon Aug 20, 2026
This issue might be a duplicate of existing issues. Please check:
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.ahosker commentedon Aug 20, 2026
Investigated on
v2(879766aee7) — the core claim does not reproduce as described.The catalog instructions advertise
searchas a global function inside Code Mode code, not astools.search:packages/core/src/codemode/instructions.ts:15-17— "Use `search` to discover…", renderingCodeMode.searchSignaturesearchSignatureresolves to a baresearch(input: { query, namespace, limit, offset }), with notools.prefixpackages/codemode/src/interpreter/runtime.ts:306registerssearchas a reserved interpreter global (SearchFunction), dispatched atruntime.ts:2001viaToolRuntime.search(interpreter/execute.ts:51)Verified directly against the v2 runtime:
Invalid assumptions in the report:
tools.$codemode.searchregistration and noreservedNamespacesymbol anywhere inpackages/codemode/src(or anywhere on the v2 tree). The citedmakeSearchToolis internal wiring for the interpreter-globalsearch, not a namespaced tool.tools.search;git grep 'tools.search'matches only the internal interpreter wiring.Unknown tool 'search'error only occurs if an agent choosestools.searchdespite 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 callingtools.searchmay not infer it means the bare global. Suggested fix for maintainers: reword the hints intool-runtime.tsto e.g. "Call the globalsearch({ query })function to find available tools." (and similarly for the stale-signature hint at line ~540), plus update the two expectations inpackages/codemode/test/tool-paths.test.ts.opencode-agent commentedon Aug 20, 2026
Thanks for the report. This appears to be based on the
devbranch rather than the currentv2implementation.On
v2, the catalog intentionally advertises baresearch(...):packages/core/src/codemode/instructions.tsrenders “Usesearch” and the baresearchsignature.packages/codemode/src/interpreter/runtime.tsregisterssearchdirectly in the interpreter global scope.packages/codemode/src/interpreter/execute.tswires that global totools.searchinternally on the host-side runtime; that internal property is not the model-facing call syntax.packages/codemode/test/codemode.test.tsverifies direct calls such assearch({ query: "file" })andsearch({}).There is no
reservedNamespaceortools.$codemode.searchregistration in the currentv2tree.tools.search(...)is therefore not the advertised call—the correct Code Mode call is the globalsearch(...).