fix(agents): strip null-valued optional args from MCP tool calls#96729
fix(agents): strip null-valued optional args from MCP tool calls#96729maweibin wants to merge 2 commits into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 25, 2026, 9:22 PM ET / 01:22 UTC. Summary PR surface: Source +93, Tests +114. Total +207 across 4 files. Reproducibility: no. high-confidence live reproduction was run in this review. Source inspection and the reporter's evidence show the current shipped path can coerce MCP nullable string nulls to empty strings, but the PR still needs configured OpenClaw MCP proof. Review metrics: 3 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land one canonical fix that preserves schema-declared nullable nulls, strips only schema-proven optional non-nullable nulls before validation, and includes redacted configured OpenClaw MCP proof. Do we have a high-confidence way to reproduce the issue? No high-confidence live reproduction was run in this review. Source inspection and the reporter's evidence show the current shipped path can coerce MCP nullable string nulls to empty strings, but the PR still needs configured OpenClaw MCP proof. Is this the best way to solve the issue? No, not as currently shaped. The nullable-union validation change is useful, but the advertised null stripping belongs before validation or the branch should be narrowed to validation-only behavior. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 6830aa39eaa1. Label changesLabel justifications:
Evidence reviewedPR surface: Source +93, Tests +114. Total +207 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
2 similar comments
|
@clawsweeper re-review |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
LLM-generated MCP tool call arguments often contain null for unset
optional parameters. Two-layer fix:
1. Validation layer (coerceWithUnionSchema): exact type match before
coercion, so null in anyOf [{string}, {null}] stays null.
2. Runtime boundary (createExecute): schema-aware null stripping via
isFieldNullableInSchema() preserves nulls for fields declared
nullable (type:null, type:["string","null"], anyOf/oneOf null
variant) and strips only non-nullable nulls.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
efda1eb to
56bb624
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
@clawsweeper re-review |
Improve the MCP null-argument fix to be schema-aware: - Only strip null values for fields NOT declared as nullable in the tool's input schema (handles type:null, type:[...,null], anyOf/oneOf with null variant, nullable:true) - Preserves null for schema-meaningful nulls (anyOf [string, null]) This approach is based on competitor PR openclaw#96729 (maweibin) which correctly handles the distinction between nullable and non-nullable fields at the MCP boundary. Fixes openclaw#96716 Signed-off-by: 赵旺0668001248 <[email protected]>
What Problem This Solves
LLM-generated MCP tool call arguments often contain
nullfor unset optional parameters. Some MCP servers treat JSONnulldifferently from an absent key — coercingnullto""and causing spurious failures. Other MCP clients (Cursor, Claude Desktop) already strip null keys before sending.This fix addresses the problem at two layers:
coerceWithUnionSchemanow prefers exact type matches over coercion, sonullinanyOf [{string}, {null}]staysnullinstead of being coerced to"".stripNullOptionalArgspreserves nulls for fields declared nullable in the tool's JSON Schema (type: "null",type: ["string", "null"],anyOf/oneOfwith null variant) and strips only non-nullable nulls.Evidence
Real MCP SDK Server proof — Uses the actual @modelcontextprotocol/sdk Server and Client (InMemoryTransport) connected through a real MCP protocol transport. The fix at the
materializeBundleMcpToolsForRun→callToolboundary strips non-nullable nulls before forwarding to the real MCP server:The proof chain:
insight_id(anyOf [{string}, {null}])materializeBundleMcpToolsForRungets the schema from a realtools/listresponseinsight_id: null(preserved) butextrastrippedFocused validation:
Format:
oxfmt --checkclean,oxlintclean,git diff --checkno output.Inline proof script:
AI-assisted: Claude Code (Anthropic).