Preserve Zod v4 schemas when cloning custom tool definitions - #1339
Closed
alexander-alex-roy wants to merge 1 commit into
Closed
Preserve Zod v4 schemas when cloning custom tool definitions#1339alexander-alex-roy wants to merge 1 commit into
alexander-alex-roy wants to merge 1 commit into
Conversation
alexander-alex-roy
deleted the
fix/mcp-tool-params-lost-to-clonedeep
branch
September 12, 2026 18:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1306.
What
MCP tool parameters were arriving at MCP servers as
{}. The cause waslodash.cloneDeepapplied to custom tool definitions in three places:getToolSet(packages/agent-runtime/src/tools/prompts.ts),additionalToolDefinitions(packages/agent-runtime/src/run-agent-step.ts), andexecuteCustomToolCall(packages/agent-runtime/src/tools/tool-executor.ts).Why
Zod v4 keeps its engine in the non-enumerable
_zodfield, whichcloneDeepdoes not copy. The cloned schema keeps a copiedsafeParse, soensureZodSchemastill accepts it as a Zod schema, but anyz.toJSONSchema()call then crashes on the missing_zod(schema._zod.defis undefined — even reading.descriptionthrows viaschema._zod.parent). The tool's params collapse to{}orgetToolSetthrows outright. I reproduced this end-to-end throughgetToolSetbefore fixing.Change
cloneToolDefinition/cloneCustomToolDefinitionshelpers inpackages/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.cloneDeepcall sites with the Zod-aware helpers. No backend, billing, or deployment paths touched.packages/agent-runtime/src/__tests__/prompts-schema-handling.test.ts: schema identity and_zodpreserved, JSON-schema defs still deep-cloned without aliasing, and end-to-endgetToolSetservingquery/max_resultsafter the clone path.Verification
prompts-schema-handling.test.ts: 19/20 pass, including all 3 new tests. The single failure (allOfrepresentation) is pre-existing on clean main. The fix also repaired a second pre-existing failure (getToolSet handles custom tools with problematic schemas).run-agent-step-tools,to-token-count-input-schema,tool-validation-error,loop-agent-steps): 70/70 pass.