fix: sanitize tool schemas for strict mode#5410
Conversation
Pydantic schemas intermittently fail strict tool-use on openai, anthropic, and bedrock. All three reject nested objects missing additionalProperties: false, and anthropic also rejects keywords like minLength and top-level anyOf. Adds per-provider sanitizers that inline refs, close objects, mark every property required, preserve nullable unions, and strip keywords each grammar compiler rejects. Verified against real bedrock, anthropic, and openai.
iris-clawd
left a comment
There was a problem hiding this comment.
This is the proper fix for the strict mode issue I flagged on #5388. Clean architecture:
Common pipeline (_common_strict_pipeline): resolve refs → strip $defs → oneOf→anyOf → ensure types → additionalProperties: false → require all properties → strip metadata — covers what all three providers need.
Per-provider sanitizers:
- OpenAI: common + strip unsupported formats
- Anthropic: common +
lift_top_level_anyof(Claude rejects top-level unions) + strip Claude-specific keywords (numeric/string constraints, pattern, etc.) - Bedrock: delegates to Anthropic (same grammar compiler) — correct and DRY
Integration:
- All three providers now conditionally sanitize only when
strictis enabled — non-strict tools pass through unchanged - OpenAI's old
force_additional_properties_falsereplaced with the fuller pipeline - Lazy imports moved to module-level (cleaner)
Verified against real Bedrock Sonnet 4.5, Anthropic, and OpenAI APIs. Unit tests noted as TODO — worth adding but not blocking.
LGTM 🚀 💬 221
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e3fb1b8. Configure here.

Summary
Pydantic schemas intermittently fail strict tool-use on openai, anthropic, and bedrock. All three reject nested objects missing
additionalProperties: false, and anthropic also rejectsminLength/maximum/top-levelanyOf. Adds per-provider sanitizers wired into each provider's tool conversion.Gemini and azure are follow-ups.
Verification
Ran the original bug-report schema against real APIs:
additionalProperties must be explicitly set to falsechat_id: nullpreservedTest plan
Note
Medium Risk
Changes tool schema generation in strict mode across three providers, which can affect tool-calling behavior and may surface new validation edge cases for existing tool definitions.
Overview
Fixes intermittent strict tool-use failures by sanitizing tool JSON schemas when
strictis enabled for OpenAI, Anthropic, and Bedrock.Adds provider-specific sanitizers in
pydantic_schema_utilsthat inline refs, forceadditionalProperties: false, require all properties, and strip unsupported/metadata keys (plus Anthropic/Bedrock-specific removals like top-levelanyOfand numeric/string constraints). Providers now apply these sanitizers during tool conversion instead of passing raw Pydantic schemas.Reviewed by Cursor Bugbot for commit e3fb1b8. Bugbot is set up for automated code reviews on this repo. Configure here.