Skip to content

[v5.0] fix: Bedrock Claude structured outputs fail with thinking on supported models - #17757

Merged
lgrammel merged 5 commits into
release-v5.0from
bugfix/11227-2
Jul 22, 2026
Merged

[v5.0] fix: Bedrock Claude structured outputs fail with thinking on supported models#17757
lgrammel merged 5 commits into
release-v5.0from
bugfix/11227-2

Conversation

@lgrammel

@lgrammel lgrammel commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Background

Bedrock structured output used a required synthetic JSON tool, which conflicts with Claude thinking, while supported Claude 4.5 and 4.6 models can use native structured output.

Root Cause

The Bedrock provider always represented JSON schemas as a required synthetic tool, forcing tool use with thinking. Request-shape tests and successful live Bedrock calls confirmed that supported models instead accept sanitized native output_config.format schemas.

Summary

Supported Bedrock Claude models now use sanitized native structured-output schemas when fixed or adaptive thinking is enabled, without toolConfig. Unsupported models retain the existing fallback, the Anthropic sanitizer is exported through @ai-sdk/anthropic/internal, effort settings are preserved, and the changeset patches both packages.

Testing

Regression coverage verifies fixed and adaptive thinking, schema sanitization, effort merging, unsupported-model fallback, omission of forced tool configuration, and returned JSON text. Amazon Bedrock Node and edge suites each pass 225 tests; both package type checks, builds, and formatting checks pass.

End-to-end Validation

  • AWS_REGION=us-east-1 pnpm --filter @example/ai-core exec tsx -e '<Opus 4.5 fixed-thinking constrained schema>' returned {"answer":"ok","score":1}.
  • AWS_REGION=us-east-1 pnpm --filter @example/ai-core exec tsx -e '<Opus 4.6 adaptive-thinking schema>' returned {"answer":"ok"}.

Related Issues

Fixes #11227

Closes #17729

Co-authored-by: lgrammel 205036+lgrammel@users.noreply.github.com

@lgrammel

Copy link
Copy Markdown
Collaborator Author

Bugfix review

Outcome: changes-required

Reproduction replay

Status: no-longer-reproduces

The exact original reproduction completed successfully and the original bug signal did not appear.

Fixes issue

Status: partially-addresses

The fix works for the reproduced simple schema on supported Claude 4.5/4.6 models, but it applies native structured output to every Anthropic model and forwards schemas that Bedrock may reject.

Concerns:

  • The new condition selects native output for any thinking-enabled Anthropic model. AWS lists native structured output only for specific Claude 4.5/4.6 models, excluding the reported Sonnet 4.0 case, so that model still cannot return the expected object.
  • The schema is forwarded without the existing Anthropic sanitizeJsonSchema normalization. Bedrock rejects common constraints such as minimum, maximum, minLength, and maxLength, so many Output.object() schemas can still fail with HTTP 400.

Side effects

Risk: medium

Non-thinking and non-Anthropic behavior remains unchanged, but unsupported Anthropic models now receive an unsupported output_config payload instead of the synthetic tool configuration.

Concerns:

  • The model-unconditional Anthropic check can turn the original forced-tool failure into a different provider validation failure on models without native structured-output support.

Performance

Risk: low

The change adds no local caches, loops, or unbounded allocations; native schema compilation is provider-side, although a new schema can have first-use compilation latency.

Backwards compatibility

Risk: none

The change does not read, migrate, mutate, or reinterpret stored application data.

Architecture

Risk: medium

The implementation remains inside the Bedrock provider, but it bypasses an existing Anthropic-owned abstraction required for correctly preparing output_config schemas.

Concerns:

  • packages/anthropic already owns sanitizeJsonSchema for Anthropic native structured output. The Bedrock provider should consume it through @ai-sdk/anthropic/internal after declaring the export, rather than serializing raw Anthropic schemas or importing another package's src directory.

Change scope

Status: has-unnecessary-changes

The changeset, provider fix, and regression test are relevant, but one production hunk changes unrelated option-merging behavior.

Concerns:

  • Preserving arbitrary existing output_config fields in the maxReasoningEffort branch is not needed to combine the newly generated format with effort because the native-output block runs afterward and already merges effort; this separate behavior change is untested.

Security

Risk: none

No credential handling, authorization, input execution, network destination, or sensitive-data behavior is introduced.

Testing

Status: needs-more

The added generate-path regression passes, as do the package Node and edge suites and type-check, but the test uses Claude 3 Haiku and therefore codifies native output for an unsupported model.

Concerns:

  • Use a supported Claude 4.5/4.6 model ID in the unit test and add a test proving unsupported models are handled without sending invalid output_config.
  • Add coverage showing common unsupported JSON Schema constraints are sanitized before being sent.
  • Adaptive thinking is included by the production condition but is not covered by the new regression test.

Verification

Reviewed the complete three-file merge-base diff, inspected the provider's request and response paths, compared the existing Anthropic schema sanitizer and later Bedrock implementation, and ran the Amazon Bedrock Node suite, edge suite, type-check, and diff validation successfully.

Relevant Documentation

@lgrammel lgrammel changed the title [v5.0] fix: allow Bedrock Claude structured outputs when thinking is enabled [v5.0] fix: Bedrock Claude structured outputs fail with thinking on supported models Jul 22, 2026
@lgrammel

Copy link
Copy Markdown
Collaborator Author

Addressed PR comment 5047547423.

Bugfix review

Outcome: changes-required

Reproduction replay

Status: no-longer-reproduces

... 81 more line(s) omitted

Restricted native output_config generation to the documented supported Claude model IDs, exported and reused Anthropic's sanitizeJsonSchema helper, and removed the unrelated preservation of arbitrary output_config fields from the maxReasoningEffort branch. The tests now use supported Claude 4.5 and 4.6 IDs and cover constraint sanitization, adaptive thinking with effort, and unsupported models receiving no native output_config. Unsupported models retain the synthetic-tool fallback because Bedrock provides no native structured-output path for them. Node, edge, type, formatting, build, and live fixed/adaptive-thinking checks pass.

@lgrammel

Copy link
Copy Markdown
Collaborator Author

Bugfix review

Outcome: changes-required

Reproduction replay

Status: no-longer-reproduces

The exact original reproduction completed successfully and the original bug signal did not appear.

Fixes issue

Status: partially-addresses

The implementation fixes supported Claude 4.5/4.6 requests in the checkout, but its required cross-package export is not independently releasable with the current changeset.

Concerns:

  • The Bedrock package now imports sanitizeJsonSchema from @ai-sdk/anthropic/internal, but the changeset only bumps @ai-sdk/amazon-bedrock. A release following that declaration can install an older Anthropic package without the new named export.

Side effects

Risk: high

The runtime logic is narrowly gated, but incorrect package release coordination could prevent the published Bedrock provider from importing at all.

Concerns:

  • The built Bedrock entry point has a top-level named import of sanitizeJsonSchema. Publishing Bedrock without a corresponding Anthropic release can cause module initialization failure, affecting uses unrelated to structured output.

Performance

Risk: low

Schema sanitization performs a bounded recursive copy proportional to the supplied schema and introduces no persistent caches, unbounded loops, or retained request state.

Backwards compatibility

Risk: none

The change does not read, migrate, mutate, or reinterpret existing stored data.

Architecture

Risk: medium

Reusing the Anthropic-owned sanitizer through its declared internal export preserves package ownership, but the owning package is missing from the release declaration.

Concerns:

  • Cross-package runtime API additions must version and publish the owning package alongside consumers. The equivalent sanitizer changes on other release lines include patch changesets for both Amazon Bedrock and Anthropic.

Change scope

Status: unclear

The production code and tests are focused, but the release scope is incomplete because the changed Anthropic package is omitted from the changeset.

Concerns:

  • Add @ai-sdk/anthropic as a patch entry to the changeset so the new internal export is published with the Bedrock fix.

Security

Risk: none

The change introduces no credential handling, authorization changes, executable input, network destination changes, or sensitive-data exposure.

Testing

Status: appropriate

Regression tests cover fixed and adaptive thinking, schema sanitization, effort merging, native JSON text responses, omission of forced tool configuration, and unsupported-model fallback.

Verification

Inspected the complete four-file merge-base diff, package exports and dependency boundaries, request and response paths, model gating, schema sanitizer ownership, and release metadata. Amazon Bedrock Node and edge suites each passed all 225 tests, both Amazon Bedrock and Anthropic type checks passed, diff validation passed, and changeset inspection confirmed Anthropic is not declared for this PR's release.

Relevant Documentation

@lgrammel

Copy link
Copy Markdown
Collaborator Author

Addressed PR comment 5047547423.

Bugfix review

Outcome: changes-required

Reproduction replay

Status: no-longer-reproduces

... 81 more line(s) omitted

Addressed the model gating, sanitizer ownership, option-merging, and coverage concerns. Native output is restricted to supported Claude 4.5/4.6 IDs, schemas use sanitizeJsonSchema through @ai-sdk/anthropic/internal, unsupported models retain the prior fallback, and tests cover fixed and adaptive thinking, sanitization, effort merging, toolConfig omission, fallback behavior, and JSON text responses.

@lgrammel

Copy link
Copy Markdown
Collaborator Author

Addressed PR comment 5047845597.

Bugfix review

Outcome: changes-required

Reproduction replay

Status: no-longer-reproduces

... 72 more line(s) omitted

Added @ai-sdk/anthropic as a patch entry in the existing changeset so the new internal export is released with its Amazon Bedrock consumer. Rebuilt both packages and verified that the built Anthropic internal entry exports sanitizeJsonSchema and the built Bedrock entry imports it successfully.

@lgrammel

Copy link
Copy Markdown
Collaborator Author

Bugfix review

Outcome: approved

Reproduction replay

Status: no-longer-reproduces

The exact original reproduction completed successfully and the original bug signal did not appear.

Fixes issue

Status: fully-addresses

Thinking-enabled structured output now uses sanitized native output_config.format for the Bedrock Claude models documented to support it, while unsupported models retain the existing fallback.

Side effects

Risk: low

The new behavior is restricted to supported Anthropic models when both thinking and a JSON schema are requested; non-thinking, non-Anthropic, and unsupported-model paths remain unchanged.

Performance

Risk: low

Schema sanitization creates a request-scoped copy proportional to schema size and introduces no persistent cache, retained state, or additional network request.

Backwards compatibility

Risk: none

The change does not read, migrate, mutate, or reinterpret stored application data.

Architecture

Risk: low

Anthropic-specific schema normalization remains owned by the Anthropic package and is consumed through its declared internal export; both producer and consumer receive coordinated patch releases, with no cross-package src import.

Change scope

Status: minimal

All four changed files are necessary: provider request selection, regression coverage, the owning package's internal export, and coordinated release metadata.

Security

Risk: none

The change introduces no credential, authorization, executable-input, network-destination, or sensitive-data handling changes.

Testing

Status: appropriate

Regression tests cover fixed and adaptive thinking, supported and unsupported model selection, schema sanitization, effort merging, omission of forced toolConfig, and native JSON text responses.

Verification

Reviewed the complete merge-base diff and relevant package boundaries, confirmed the coordinated changeset, and verified diff integrity, formatting, linting, both package type checks, and the Amazon Bedrock Node and edge suites with all 225 tests passing in each environment.

Relevant Documentation

@lgrammel
lgrammel merged commit 1b0e540 into release-v5.0 Jul 22, 2026
53 of 54 checks passed
@lgrammel
lgrammel deleted the bugfix/11227-2 branch July 22, 2026 15:54
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Published in:

Package Version
ai 5.0.219 github npm
@ai-sdk/amazon-bedrock 3.0.109 github npm
@ai-sdk/angular 1.0.219 github npm
@ai-sdk/anthropic 2.0.89 github npm
@ai-sdk/anthropic-aws 0.1.4 github npm
@ai-sdk/gateway 2.0.118 github npm
@ai-sdk/google-vertex 3.0.156 github npm
@ai-sdk/langchain 1.0.219 github npm
@ai-sdk/llamaindex 1.0.219 github npm
@ai-sdk/react 2.0.221 github npm
@ai-sdk/rsc 1.0.221 github npm
@ai-sdk/svelte 3.0.219 github npm
@ai-sdk/vue 2.0.219 github npm

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.

1 participant