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
{{ message }}
Repository navigation
Tool outputSchema is generated in validation mode, so serialization aliases and computed fields don't match structuredContent #3644
On v2 (2118f14), a tool returning a model with a serialization_alias or a @computed_field advertises an outputSchema that its own structuredContent violates:
Clients that validate structuredContent against outputSchema (as the spec says they should) reject these results. camelCase serialization aliases are common for JS-facing tools, so this hits anyone using them.
I had a fix for this in #3118 (closed in the v2 cleanup) and can port it to v2 with a regression test if you'd like to assign this to me.
The mismatch comes from generating the output schema in validation mode while the result is serialized in serialization mode, and aliases plus computed fields are exactly where the two diverge: user_id in the schema, userId and doubled in structuredContent.
For each mechanism:
Aliases: model_json_schema() defaults to validation mode, which uses field names. The value returned by convert_result goes through serialization (by_alias=True), so the schema needs mode='serialization' to track it. The general split that stays consistent: input schemas in validation mode (they describe what clients send), output schemas in serialization mode (they describe what the SDK emits). That matches the data direction of each contract.
Computed fields: whether a @computed_field appears in the schema depends on model config and pydantic version defaults. The safe pattern is to derive the schema and the serialization from one configuration, so if a computed field is emitted it is also declared in the schema. Your repro is the right regression check to encode: set(output_schema["properties"]) == set(convert_result(...).structured_content), run for a couple of representative models.
Worth adding to the fix: a validation pass in the SDK that checks the produced structuredContent against the generated outputSchema before it leaves the server, enabled at least in the test suite. Clients that validate (as the spec tells them to) will reject a mismatch anyway; failing inside the SDK's own tests makes this class of bug impossible to ship silently.
Your #3118 work mapped exactly this area, so porting it with alias and computed-field cases as separate regression tests, plus one nested-model case where partial fixes usually show up, should close it cleanly.
@maxisbey since this is labeled for both v1 and v2: the fix I'd port is small. Generate the output schema with mode="serialization" in FuncMetadata.model_post_init, and when a tool returns its own CallToolResult, dump the validated structured_content with by_alias=True so it matches that schema. Regression test with a serialization alias and a computed field, on v2 first. Happy to take it if you assign it to me.
This is the same validation-versus-serialization outputSchema mismatch tracked in #3100, including serialization aliases and computed fields. Closing as a duplicate. AI-assisted triage; I reviewed both reports.
Activity
Ben-Home commentedon Oct 5, 2026
The mismatch comes from generating the output schema in validation mode while the result is serialized in serialization mode, and aliases plus computed fields are exactly where the two diverge: user_id in the schema, userId and doubled in structuredContent.
For each mechanism:
Worth adding to the fix: a validation pass in the SDK that checks the produced structuredContent against the generated outputSchema before it leaves the server, enabled at least in the test suite. Clients that validate (as the spec tells them to) will reject a mismatch anyway; failing inside the SDK's own tests makes this class of bug impossible to ship silently.
Your #3118 work mapped exactly this area, so porting it with alias and computed-field cases as separate regression tests, plus one nested-model case where partial fixes usually show up, should close it cleanly.
jayzuccarelli commentedon Oct 6, 2026
@maxisbey since this is labeled for both v1 and v2: the fix I'd port is small. Generate the output schema with
mode="serialization"inFuncMetadata.model_post_init, and when a tool returns its ownCallToolResult, dump the validatedstructured_contentwithby_alias=Trueso it matches that schema. Regression test with a serialization alias and a computed field, on v2 first. Happy to take it if you assign it to me.Kludex commentedon Oct 10, 2026
This is the same validation-versus-serialization
outputSchemamismatch tracked in #3100, including serialization aliases and computed fields. Closing as a duplicate. AI-assisted triage; I reviewed both reports.