Skip to content

Preserve Zod v4 schemas when cloning custom tool definitions - #1339

Closed
alexander-alex-roy wants to merge 1 commit into
CodebuffAI:mainfrom
alexander-alex-roy:fix/mcp-tool-params-lost-to-clonedeep
Closed

Preserve Zod v4 schemas when cloning custom tool definitions#1339
alexander-alex-roy wants to merge 1 commit into
CodebuffAI:mainfrom
alexander-alex-roy:fix/mcp-tool-params-lost-to-clonedeep

Conversation

@alexander-alex-roy

Copy link
Copy Markdown

Fixes #1306.

What

MCP tool parameters were arriving at MCP servers as {}. The cause was lodash.cloneDeep applied to custom tool definitions in three places: getToolSet (packages/agent-runtime/src/tools/prompts.ts), additionalToolDefinitions (packages/agent-runtime/src/run-agent-step.ts), and executeCustomToolCall (packages/agent-runtime/src/tools/tool-executor.ts).

Why

Zod v4 keeps its engine in the non-enumerable _zod field, which cloneDeep does not copy. The cloned schema keeps a copied safeParse, so ensureZodSchema still accepts it as a Zod schema, but any z.toJSONSchema() call then crashes on the missing _zod (schema._zod.def is undefined — even reading .description throws via schema._zod.parent). The tool's params collapse to {} or getToolSet throws outright. I reproduced this end-to-end through getToolSet before fixing.

Change

  • Added exported cloneToolDefinition / cloneCustomToolDefinitions helpers in packages/agent-runtime/src/tools/prompts.ts: genuine Zod schemas (instanceof z.ZodType) are kept by reference since they are treated as immutable downstream; plain JSON Schema objects and remaining fields are still deep-cloned.
  • Replaced the three cloneDeep call sites with the Zod-aware helpers. No backend, billing, or deployment paths touched.
  • Added three regression tests to packages/agent-runtime/src/__tests__/prompts-schema-handling.test.ts: schema identity and _zod preserved, JSON-schema defs still deep-cloned without aliasing, and end-to-end getToolSet serving query/max_results after the clone path.

Verification

  • prompts-schema-handling.test.ts: 19/20 pass, including all 3 new tests. The single failure (allOf representation) is pre-existing on clean main. The fix also repaired a second pre-existing failure (getToolSet handles custom tools with problematic schemas).
  • Neighbor suites (run-agent-step-tools, to-token-count-input-schema, tool-validation-error, loop-agent-steps): 70/70 pass.
  • Package typecheck shows no errors in the touched files.

@alexander-alex-roy
alexander-alex-roy deleted the fix/mcp-tool-params-lost-to-clonedeep branch September 12, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant