Harden client tool result error handling#3778
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3f8cadc9b
ℹ️ 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".
c22eaa2 to
2655726
Compare
jlowin
left a comment
There was a problem hiding this comment.
Thanks for the PR. The empty content and non-text content guards are reasonable — that cast + blind index is genuinely fragile, and guarding it is the right call.
However, please revert the except Exception narrowing back to except Exception. That catch-all is intentional: the structured content parsing pipeline involves schema lookup, type coercion, and Pydantic validation, and we don't want any failure there to crash the tool call. Narrowing to a hand-picked list of exceptions is just predicting what might go wrong — the whole point is to handle what we didn't predict.
Also, for future reference — we generally expect bug fix PRs to reference an existing issue or provide a concrete reproduction (which server produces these edge cases?). The fixes here are defensible from reading the code, so I'm not going to block on that, but it helps us prioritize.
|
Makes sense on |
2655726 to
40be7d6
Compare
- Bump fastmcp dep to >=3.2.1 (includes PrefectHQ/fastmcp#3778 client call_tool error handling for empty/non-text error content) - Add python_version>=3.10 marker on temporalio dep - Fix docs/mcp.md: add timestamp arg to warrant.sign() examples, correct LangChain adapter pattern to use guard_tools(), fix call_protected_tool -> call_tool, clarify extraction result - Fix fastmcp_middleware: strip tenuo from context-resolved _meta when params.meta is None
…#341) Extracts useful changes from the now-stale `mcp/fastmcp-middleware-client-errors` branch that weren't part of #339 or #340. - Bump `fastmcp` dep to `>=3.2.1` (includes upstream [client call_tool error handling](PrefectHQ/fastmcp#3778)) - Add `python_version>=3.10` marker on `temporalio` dep - Fix `docs/mcp.md`: add timestamp arg to `warrant.sign()` examples, correct LangChain adapter pattern to use `guard_tools()`, fix `call_protected_tool` → `call_tool` - Fix `fastmcp_middleware.py`: strip `tenuo` from context-resolved `_meta` when `params.meta` is None
Description
_parse_call_tool_resultcrashes on error results with empty or non-text content, and parsesstructuredContenton error results through the success validation pipeline. These surface when connecting to non-FastMCP servers that don't produceTextContenton errors.Bugs fixed:
isError=Truewith no content blocks raisesIndexError. MCP does not mandate text on errors, so third-party servers can legally return empty content.TextContent, thecast()call raisesAttributeError.isError=Trueresults withstructuredContentfall through to the success parsing pipeline, attempting schema validation against a diagnostic payload.Changes:
isinstanceand falls back to a tool-name-scoped message.structuredContentbranch requiresnot result.isError.except Exceptionnarrowed to(ValidationError, KeyError, TypeError, ValueError)so unexpected exceptions propagate instead of being logged and dropped.Contribution type
Checklist
uv run prek run --all-filesand all checks pass