Skip to content

fix(codemode): stop leaking undefined into tool arguments#37652

Merged
rekram1-node merged 2 commits into
v2from
json-outbound-args
Jul 18, 2026
Merged

fix(codemode): stop leaking undefined into tool arguments#37652
rekram1-node merged 2 commits into
v2from
json-outbound-args

Conversation

@rekram1-node

Copy link
Copy Markdown
Collaborator

Closes the outbound-handling gap from interpreter-support.md (previously an unchecked item). Tool arguments now cross the boundary with JSON.stringify semantics instead of passing raw undefined through to tools.

Behavior

For tools.api.search({ q: undefined, limit: 0/0, items: [1, undefined, 2] }) the tool now receives:

{ limit: null, items: [1, null, 2] }   // q dropped, NaN -> null, undefined element -> null
  • Object properties with undefined values are dropped, like JSON
  • undefined array elements and sparse holes become null
  • Non-finite numbers become null (pre-existing behavior, unchanged)
  • A bare tools.t(undefined) still reaches schema decoding as undefined (matches JSON.stringify(undefined) being undefined)

The headline user-visible improvement: the ubiquitous { query: cond ? value : undefined } idiom now works against Effect schemas using optionalKey, which reject a present undefined value. Previously that call failed decoding; now the key is dropped before the schema runs — matching what any JSON-transported tool call would see.

Program results deliberately keep the stricter normalization (undefined -> null everywhere), as do console.table columns.

Implementation

copyOut(value, undefinedAsNull?: boolean) becomes copyOut(value, mode: "raw" | "nullify" | "json") in tool-runtime.ts. Tool invoke and built-in search args use "json"; execution results and console.table use "nullify" (the old true); errors.ts/json.ts keep "raw" (the old default) where native JSON.stringify already applies these semantics itself.

Testing

  • Unit tests pin json/nullify/raw modes against real JSON.stringify behavior
  • End-to-end tests pin what a render-only JSON-Schema tool receives (dropped key asserted via Object.hasOwn), sparse-hole densification, and the optionalKey acceptance change for both a user tool and the built-in search
  • interpreter-support.md updated in the same PR; 911 tests pass from packages/codemode

@rekram1-node rekram1-node changed the title feat(codemode): JSON serialization semantics for outbound tool arguments fix(codemode): stop leaking undefined into tool arguments Jul 18, 2026
@rekram1-node
rekram1-node merged commit 33f1b26 into v2 Jul 18, 2026
9 of 10 checks passed
@rekram1-node
rekram1-node deleted the json-outbound-args branch July 18, 2026 18:42
github-actions Bot pushed a commit to ReStranger/opencode that referenced this pull request Jul 19, 2026
* upstream/v2:
  mini: fix shell tool output display (anomalyco#37711)
  fix(core): detach disposed MCP registrations from root scope (anomalyco#37660)
  fix(core): preserve the first terminal failure (anomalyco#37705)
  fix(core): continue after malformed tool input (anomalyco#37701)
  fix(core): safely recover malformed tool input (anomalyco#37698)
  fix(simulation): render screenshot symbol glyphs (anomalyco#37691)
  fix(core): authorize relative external paths (anomalyco#37689)
  fix(tui): auto-approve permissions in auto mode
  feat(core): allow MCP Code Mode opt-out (anomalyco#37681)
  fix(codemode): stop leaking undefined into tool arguments (anomalyco#37652)
  fix(tui): style interrupted compaction neutrally (anomalyco#37655)
  fix(cli): harden managed service election (anomalyco#37645)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant