Skip to content

fix(anthropic): sanitize unsupported JSON Schema keywords in structured output schemas#14372

Open
vigneshakaviki wants to merge 4 commits intovercel:mainfrom
vigneshakaviki:fix/anthropic-structured-output-schema-sanitize
Open

fix(anthropic): sanitize unsupported JSON Schema keywords in structured output schemas#14372
vigneshakaviki wants to merge 4 commits intovercel:mainfrom
vigneshakaviki:fix/anthropic-structured-output-schema-sanitize

Conversation

@vigneshakaviki
Copy link
Copy Markdown

@vigneshakaviki vigneshakaviki commented Apr 13, 2026

Summary

  • Anthropic's output_config.format.schema strictly rejects unsupported JSON Schema keywords (exclusiveMinimum, minimum, maximum, not, pattern, etc.), unlike tool schemas where they are silently ignored
  • Leverages Anthropic SDK's built-in transformJSONSchema to sanitize schemas before passing to output_config.format.schema
  • The SDK sanitizer handles: stripping unsupported keywords, moving them to description as model hints, converting oneOf to anyOf, enforcing additionalProperties: false, and filtering string format values

Test plan

  • Added unit tests covering unsupported keyword stripping, description hints, nested schemas, and the reproduction case from the issue
  • All existing node and edge tests pass
  • Changeset added

Fixes #14342

Covers stripping of unsupported keywords like exclusiveMinimum, minimum,
maximum, pattern, minLength, not, etc. from schemas passed to
output_config.format.schema.

Ref: vercel#14342
…ed output schemas

Anthropic's output_config.format.schema strictly rejects validation-only
JSON Schema keywords (exclusiveMinimum, minimum, maximum, not, pattern,
etc.), unlike tool schemas where they are silently ignored. This caused
valid Zod schemas like z.number().positive() to produce 400 errors.

Add sanitizeJsonSchema() that recursively strips unsupported keywords
while preserving structural and composition keywords.

Fixes: vercel#14342
@tigent tigent bot added ai/provider related to a provider package. Must be assigned together with at least one `provider/*` label bug Something isn't working as documented provider/anthropic Issues related to the @ai-sdk/anthropic provider labels Apr 13, 2026
Comment thread packages/anthropic/src/sanitize-json-schema.ts Outdated
…ma sanitization

Replace custom sanitizer with Anthropic SDK's built-in transformJSONSchema,
which handles stripping unsupported keywords, moving them to description,
converting oneOf to anyOf, and enforcing additionalProperties: false.
@vigneshakaviki vigneshakaviki force-pushed the fix/anthropic-structured-output-schema-sanitize branch from f0b8835 to e0f5bda Compare April 13, 2026 16:51
Copy link
Copy Markdown
Collaborator

@aayush-kapoor aayush-kapoor left a comment

Choose a reason for hiding this comment

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

…dependency

Replace the re-export from @anthropic-ai/sdk with a self-contained
implementation of the JSON Schema sanitizer. The logic is adapted from
the SDK's transformJSONSchema but requires no external dependency.

Addresses reviewer feedback to avoid adding external dependencies.
);
}
result['type'] = type;
}
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.

JSON Schema enum and const keywords are stripped and moved to description string instead of being preserved as proper constraints in Anthropic structured output schemas.

Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai/provider related to a provider package. Must be assigned together with at least one `provider/*` label bug Something isn't working as documented provider/anthropic Issues related to the @ai-sdk/anthropic provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anthropic structured outputs fail with valid Zod schemas due to unsupported JSON Schema keywords (e.g. exclusiveMinimum, not, minimum, maximum)

2 participants