fix: remove dereference=True while calling compress_schema#3774
fix: remove dereference=True while calling compress_schema#3774Jazzcort wants to merge 1 commit intoPrefectHQ:release/2.xfrom
Conversation
This addresses the issues found in PrefectHQ#3760. Currently, if a self-referencing Pydantic data type is buried in a nested field, calling dereference_refs() introduces a circular reference to the final schema. This results in a serialization error that crashes the server during tools/list requests. I checked v3.2.0 and noticed that dereference=True is no longer being passed to compress_schema(), which essentially reverts PrefectHQ#3170. We should implement this same behavior for the 2.x versions. While the community will eventually migrate to 3.x, I think we still need to pull this fix in now because the bug causes a complete server crash whenever tools/list is called.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a53f1cfa0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| input_schema, | ||
| prune_params=prune_params, | ||
| prune_titles=True, | ||
| dereference=True, | ||
| ) |
There was a problem hiding this comment.
Keep input schemas dereferenced for client compatibility
Removing dereference=True here changes tool parameter schemas back to $ref/$defs form for common Pydantic inputs (e.g., user: UserInput), which regresses the compatibility behavior introduced for MCP clients that do not resolve JSON Schema refs. The codebase still documents this as required for clients like Copilot/Claude (src/fastmcp/utilities/json_schema.py) and existing tool-manager expectations assume inlined parameter objects, so this will make affected tools unusable in those clients rather than just changing formatting.
Useful? React with 👍 / 👎.
Test Failure AnalysisSummary: The PR removes Root Cause: The PR changed how tool input schemas are built: previously
Suggested Solution: There are two paths:
Path 2 is likely the right approach given that the existing tests exist precisely to verify MCP client compatibility. Detailed AnalysisFailing log excerpts: The PR diff removes The Codex review on this PR also flagged this concern at Related Files
|
|
Hey @jlowin, let me know what do you think about this. Do you think this is worth the fix? I can start to fix the test cases if you agree with this fix. Otherwise, you can just close this PR. 😁 |
|
Thanks for digging into this! The bug is real — recursive models nested in containers do break serialization. The history here is that dereferencing was added specifically because many MCP clients (Claude, Copilot, etc.) don't resolve In 3.x we solved this properly: the Backporting that middleware to 2.x would be a fairly involved change. Since 3.x already addresses this (and a lot more), I'd recommend upgrading if you can — it's a much better experience overall. Happy to help if you run into any migration questions. |
|
@jlowin Thank you for the detailed walkthrough of this bug! We currently have fastmcp pinned to 2.x just to streamline the process for our current release. However, we are definitely planning to upgrade to 3.x in a future release—the new features and improvements will really help simplify our implementation. Thanks for maintaining such an awesome project! We'll be sure to contribute back if we encounter any issues or think of potential improvements while using it. |
Description
This addresses the issues found in #3760. Currently, if a self-referencing Pydantic data type is buried in a nested field, calling dereference_refs() introduces a circular reference to the final schema. This results in a serialization error that crashes the server during tools/list requests.
I checked v3.2.0 and noticed that dereference=True is no longer being passed to compress_schema(), which essentially reverts #3170. We should implement this same behavior for the 2.x versions. While the community will eventually migrate to 3.x, I think we still need to pull this fix in now because the bug causes a complete server crash whenever tools/list is called.
Contribution type
Checklist
uv run prek run --all-filesand all checks pass