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
opencode-go (muse-spark-1.3-contributor; also applies to any routed model that emits OpenCode-native default.* tool names)
OpenCodex version
@bitkyc08/opencodex 2.59.0. Checked on 2026-09-22 via GitHub API against main and tag v2.60.0: CODE_MODE_HELPER_TOOL_NAMES still lists only exec_command, shell_command, write_stdin, apply_patch, view_image.
Endpoint or capability
/v1/responses streaming tool calls, Codex code mode (exec as the only top-level client tool)
Current behaviour
A Codex Desktop code-mode turn against a routed model is killed mid-stream with:
stream disconnected before completion: routed provider emitted undeclared client tool "default.update_goal"; only request-declared tools may be called
The message is produced by undeclaredToolCallMessage in src/server/responses-undeclared-tool-guard.ts. The proxy usage log records HTTP status 200 while the client rollout records the stream termination error.
Observed request: provider opencode-go, model muse-spark-1.3-contributor, inbound responses, timestamp 2026-09-22 14:00:24 (Asia/Shanghai). Upstream emitted a top-level tool call named default.update_goal instead of the code-mode nested helper, and the guard failed the stream closed.
Expected behaviour
Same contract as the code-mode helper remap for apply_patch / write_stdin / view_image / exec_command, and the precedent #4412 / #4475 established for view_image:
When the request catalog is genuine code mode (exec declared, no top-level goal tools declared), provider-emitted update_goal, default.update_goal (and sibling create_goal / get_goal) is not rejected as an undeclared client tool.
The call is restored as the declared exec custom tool, with the body compiled to the nested helper Codex runs:
The Codex code-mode exec tool description advertises tools.create_goal(args), tools.get_goal(args), and tools.update_goal(args) alongside other nested helpers; these are not wire tools.
When neither exec nor a goal tool is declared, keep fail-closed.
Minimal redacted request or reproduction
Codex Desktop in code mode: request catalog declares top-level exec (and non-helper interaction tools such as wait, request_user_input). Goal tools exist only as await tools.update_goal(...) inside exec.
Route the turn to a model that emits goal tool calls directly (observed with opencode-go/muse-spark-1.3-contributor).
Upstream emits a top-level function_call with name: "default.update_goal" and arguments: {"status":"complete"}.
normalizeDeclaredToolName strips the invented default. prefix only when the stripped name is in CODE_MODE_HELPER_TOOL_NAMES. Because update_goal is absent from that set, the guard flags the call as undeclared and terminates the stream.
Actual response or error
stream disconnected before completion: routed provider emitted undeclared client tool "default.update_goal"; only request-declared tools may be called
src/types/tools.ts: add update_goal, create_goal, get_goal to CODE_MODE_HELPER_TOOL_NAMES.
src/responses/code-mode-helper-compat.ts: add explicit compile branches in compileCodeModeHelperInput for the three goal helpers to emit const result = await tools.<helper>(<args>);\ntext(result);. Without these branches, unhandled helpers fall back to tools.exec_command(...).
Relevant test files: tests/responses/responses-undeclared-tool-guard.test.ts, tests/responses/legacy-shell-compat.test.ts, and tests/responses/responses-code-mode-patch-compile.test.ts.
Additional context
Verified locally on 2.59.0 (macOS, Codex App, opencode-go): applying both parts passes an 18-assertion test covering normalization to exec, guard acceptance, compilation to tools.update_goal(...) instead of tools.exec_command(...), and restoring the item as a custom_tool_call named exec. Undeclared tools remain rejected, and declared bare tools retain precedence.
Uncertainty: the wire trace contained literal default.update_goal in the name field. Providers sending a structured namespace field (namespace: "default", name: "update_goal") have not been observed in this setup and remain unverified; under current code, routedCustomToolTargetName returns undefined when namespace is a string.
Client or integration
Codex App (Desktop)
Provider or upstream service
opencode-go (
muse-spark-1.3-contributor; also applies to any routed model that emits OpenCode-nativedefault.*tool names)OpenCodex version
@bitkyc08/opencodex2.59.0. Checked on 2026-09-22 via GitHub API againstmainand tagv2.60.0:CODE_MODE_HELPER_TOOL_NAMESstill lists onlyexec_command,shell_command,write_stdin,apply_patch,view_image.Endpoint or capability
/v1/responsesstreaming tool calls, Codex code mode (execas the only top-level client tool)Current behaviour
A Codex Desktop code-mode turn against a routed model is killed mid-stream with:
The message is produced by
undeclaredToolCallMessageinsrc/server/responses-undeclared-tool-guard.ts. The proxy usage log records HTTP status 200 while the client rollout records the stream termination error.Observed request: provider
opencode-go, modelmuse-spark-1.3-contributor, inboundresponses, timestamp 2026-09-22 14:00:24 (Asia/Shanghai). Upstream emitted a top-level tool call nameddefault.update_goalinstead of the code-mode nested helper, and the guard failed the stream closed.Expected behaviour
Same contract as the code-mode helper remap for
apply_patch/write_stdin/view_image/exec_command, and the precedent #4412 / #4475 established forview_image:execdeclared, no top-level goal tools declared), provider-emittedupdate_goal,default.update_goal(and siblingcreate_goal/get_goal) is not rejected as an undeclared client tool.execcustom tool, with the body compiled to the nested helper Codex runs:The Codex code-mode
exectool description advertisestools.create_goal(args),tools.get_goal(args), andtools.update_goal(args)alongside other nested helpers; these are not wire tools.default.:default.view_imagerejected as undeclared #4176 / fix(responses): normalize invented default. namespace back to the declared bare tool #4264 behaviour: an inventeddefault.update_goalrewrites to bareupdate_goaland is not compiled intoexec.execnor a goal tool is declared, keep fail-closed.Minimal redacted request or reproduction
exec(and non-helper interaction tools such aswait,request_user_input). Goal tools exist only asawait tools.update_goal(...)insideexec.opencode-go/muse-spark-1.3-contributor).function_callwithname: "default.update_goal"andarguments: {"status":"complete"}.normalizeDeclaredToolNamestrips the inventeddefault.prefix only when the stripped name is inCODE_MODE_HELPER_TOOL_NAMES. Becauseupdate_goalis absent from that set, the guard flags the call as undeclared and terminates the stream.Actual response or error
Upstream documentation
exectool description):tools.create_goal,tools.get_goal,tools.update_goal.src/server/responses-undeclared-tool-guard.ts.default.view_image. Thedefault.fold branch innormalizeDeclaredToolName(commented "Code mode never declares bare helper names") is present in 2.59.0; the three goal helper names are missing fromCODE_MODE_HELPER_TOOL_NAMES.default.prefix when the bare tool is declared: [bug] routed provider prefixes bare Codex tool withdefault.:default.view_imagerejected as undeclared #4176, fixed by fix(responses): normalize invented default. namespace back to the declared bare tool #4264.Suggested mapping or implementation notes
{ exec }update_goalexec+tools.update_goal(...){ exec }default.update_goalexec+tools.update_goal(...){ update_goal }default.update_goalupdate_goal){}default.update_goalConcrete two-part change:
src/types/tools.ts: addupdate_goal,create_goal,get_goaltoCODE_MODE_HELPER_TOOL_NAMES.src/responses/code-mode-helper-compat.ts: add explicit compile branches incompileCodeModeHelperInputfor the three goal helpers to emitconst result = await tools.<helper>(<args>);\ntext(result);. Without these branches, unhandled helpers fall back totools.exec_command(...).Relevant test files:
tests/responses/responses-undeclared-tool-guard.test.ts,tests/responses/legacy-shell-compat.test.ts, andtests/responses/responses-code-mode-patch-compile.test.ts.Additional context
Verified locally on 2.59.0 (macOS, Codex App, opencode-go): applying both parts passes an 18-assertion test covering normalization to
exec, guard acceptance, compilation totools.update_goal(...)instead oftools.exec_command(...), and restoring the item as acustom_tool_callnamedexec. Undeclared tools remain rejected, and declared bare tools retain precedence.Uncertainty: the wire trace contained literal
default.update_goalin thenamefield. Providers sending a structured namespace field (namespace: "default",name: "update_goal") have not been observed in this setup and remain unverified; under current code,routedCustomToolTargetNamereturnsundefinedwhennamespaceis a string.Related: #4412 / #4475 (
view_image, closed/merged), #4176 / #4264 (bare-name fold), #3402 / #3403 (dotted names).