Skip to content

fix(mcp): route FastMCP ValidationError through the validation error handler (#42578) - #42738

Merged
rusackas merged 2 commits into
masterfrom
tdd/issue-42578-mcp-fastmcp-validationerror
Aug 5, 2026
Merged

fix(mcp): route FastMCP ValidationError through the validation error handler (#42578)#42738
rusackas merged 2 commits into
masterfrom
tdd/issue-42578-mcp-fastmcp-validationerror

Conversation

@rusackas

@rusackas rusackas commented Aug 3, 2026

Copy link
Copy Markdown
Member

SUMMARY

Fixes #42578: GlobalErrorHandlerMiddleware._handle_error in superset/mcp_service/middleware.py only matched pydantic's ValidationError via isinstance(error, ValidationError). FastMCP raises its own distinct fastmcp.exceptions.ValidationError for malformed/missing tool arguments — not a subclass of pydantic's — so those calls fell through to the generic "Internal error... contact support" response instead of a proper, client-recoverable validation message.

Root cause. Verified independently that fastmcp.exceptions.ValidationError's MRO does not include pydantic's ValidationError, and that it has no .errors() method (a plain Exception subclass with just a message), so it can't reuse pydantic's field-by-field error formatting.

Fix. Added FastMCP's ValidationError to the error classification (_USER_ERROR_TYPES, _sanitize_error_for_logging) and gave it its own dispatch branch in _handle_error that formats the message directly from str(error) instead of calling .errors().

Note: a bot comment on the issue claimed PR #41921 already fixes this. I checked that PR's diff directly — it never touches the isinstance(error, ValidationError) dispatch logic in middleware.py. This PR is the actual fix.

TESTING INSTRUCTIONS

.venv/bin/python -m pytest tests/unit_tests/mcp_service/test_middleware.py -q

The existing regression test (test_fastmcp_validation_error_routes_to_validation_branch) now passes.

ADDITIONAL INFORMATION

#42578)

fastmcp.exceptions.ValidationError (raised for malformed tool arguments)
is not a subclass of pydantic.ValidationError, the only type
GlobalErrorHandlerMiddleware._handle_error checks for, so a client-side
argument error falls through to the generic "Internal error... contact
support" branch instead of the self-correcting "Validation error in
<tool>: ..." message. Red today, confirming the bug as reported.

PR #41921 touches this same file extensively but does not change this
dispatch line -- the bug remains live despite a bot comment on the issue
claiming otherwise.
@bito-code-review

bito-code-review Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #56010e

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: 48337bb..48337bb
    • tests/unit_tests/mcp_service/test_middleware.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.59%. Comparing base (25ab961) to head (bfc1c39).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/middleware.py 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #42738      +/-   ##
==========================================
+ Coverage   65.57%   65.59%   +0.01%     
==========================================
  Files        2818     2819       +1     
  Lines      160038   160168     +130     
  Branches    36557    36570      +13     
==========================================
+ Hits       104942   105055     +113     
- Misses      53051    53064      +13     
- Partials     2045     2049       +4     
Flag Coverage Δ
hive 38.09% <0.00%> (+0.01%) ⬆️
mysql 57.92% <0.00%> (+0.05%) ⬆️
postgres 57.96% <0.00%> (+0.04%) ⬆️
presto 40.02% <0.00%> (+0.05%) ⬆️
python 59.34% <0.00%> (+0.04%) ⬆️
sqlite 57.59% <0.00%> (+0.05%) ⬆️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…handler (#42578)

GlobalErrorHandlerMiddleware._handle_error only matched pydantic's
ValidationError, not FastMCP's own distinct fastmcp.exceptions.ValidationError
(raised on malformed/missing tool arguments), so those calls fell through to
the generic "Internal error... contact support" response instead of a
client-recoverable validation message. FastMCP's ValidationError has no
.errors() API, so it gets its own message-formatting branch rather than
reusing pydantic's field-by-field details.
@rusackas rusackas changed the title test(mcp): pin FastMCP ValidationError routes to the validation branch (#42578) fix(mcp): route FastMCP ValidationError through the validation error handler (#42578) Aug 4, 2026
@netlify

netlify Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit bfc1c39
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a7133b4564edb0008365bbb
😎 Deploy Preview https://deploy-preview-42738--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@bito-code-review

bito-code-review Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #83ea3a

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: 48337bb..bfc1c39
    • superset/mcp_service/middleware.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@aminghadersohi aminghadersohi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the routing fix end to end; approving.

Routing / class match_handle_error now catches fastmcp.exceptions.ValidationError (aliased FastMCPValidationError), which is the class FastMCP's _call_tool documents it raises on tool-argument validation failure (server.py docstring + the "fastmcp's own ValidationError is a FastMCPError" comment). It is FastMCPError → Exception in the installed fastmcp — not a subclass of ToolError nor of pydantic's ValidationError, both of which are checked earlier, so the new elif is reachable and not shadowed. Confirmed against fastmcp 3.4.2. Not a no-op.

No swallow / no double-log — the branch only selects the client-facing ToolError message; the single event_logger.log(action="mcp_tool_error") sits above the if/elif and fires exactly once, unchanged from every other error type. A genuine non-validation error still falls through to the generic else ("Internal error… Error ID") untouched.

Failure classification (#42736) — the validation error is raised as ToolError, not returned as a result payload, so LoggingMiddleware.on_call_tool sets success = False via its except clause; _is_error_response is never consulted on this path. No risk of a validation failure being audited as a success.

Logging consistency (#42730) — this PR adds no new event_logger.log call; it reuses the existing _handle_error site, so it does not introduce a 4th missing-required-args instance. Audit message is sanitized via _sanitize_error_for_logging (new arm → "Request validation failed"), and _USER_ERROR_TYPES correctly reclassifies it as a WARNING-level user error. The client-facing {error} echo is symmetric with the existing pydantic/ValueError branches and describes the caller's own malformed arguments. No function-body import added.

Tests — the new test pins the handler identity (ToolError matching Validation error in execute_sql, asserts Internal error absent). Verified Rule 26: reverting only the prod elif makes it fail (falls to the generic branch). The non-validation anti-regression is covered by the existing test_unexpected_error_logs_error. Full middleware suite: 87 passed.

@rusackas

rusackas commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

@aminghadersohi appreciate the thorough pass, especially digging into whether FastMCPValidationError is actually reachable given the earlier ToolError/pydantic checks. Good confirmation the tests pin the handler identity rather than just its presence.

@rusackas
rusackas merged commit e7338a2 into master Aug 5, 2026
70 checks passed
@rusackas
rusackas deleted the tdd/issue-42578-mcp-fastmcp-validationerror branch August 5, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(mcp): FastMCP ValidationError misreported as "Internal error" — invalid tool arguments surface as a 500 to clients

3 participants