fix: anthropic fallbacks and refusal - #5367
Conversation
|
tejas ghatte seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughAnthropic now supports native server-side fallback objects, fallback boundary content blocks, stop details, fallback-credit fields, and usage model metadata across request construction and Bifrost conversions. Unsupported providers filter Anthropic-specific fields and boundary markers. ChangesAnthropic server-side fallback support
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant AnthropicRequest
participant BifrostRequest
participant AnthropicRequestBuilder
participant AnthropicResponseStream
participant BifrostResponseStream
AnthropicRequest->>BifrostRequest: route native fallbacks and credit token
BifrostRequest->>AnthropicRequestBuilder: pass typed and extra fallback parameters
AnthropicRequestBuilder->>AnthropicRequestBuilder: inject headers and filter request fields
AnthropicResponseStream->>BifrostResponseStream: convert fallback boundaries and stop details
BifrostResponseStream->>AnthropicResponseStream: reconstruct Anthropic stream events
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" Comment |
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (4): Last reviewed commit: "fix: anthropic fallbacks and refusal" | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/providers/anthropic/responses.go (1)
3438-3446: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMirror native fallback handling in
core/providers/anthropic/chat.go.ToAnthropicChatRequestshould carryExtraParams["fallbacks"]intoAnthropicMessageRequest.Fallbackslike the responses path does, so Chat requests preserve Anthropic-native fallbacks and trigger the beta header.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/anthropic/responses.go` around lines 3438 - 3446, The chat request conversion in ToAnthropicChatRequest does not propagate native fallbacks. Mirror the responses conversion by reading ExtraParams["fallbacks"], assigning it to AnthropicMessageRequest.Fallbacks, and preserving the existing behavior that triggers the beta header when fallbacks are present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@core/providers/anthropic/utils.go`:
- Around line 1285-1317: Gate native fallback preservation on the target
provider’s ServerSideFallback capability. Update stripBifrostFallbacksFromBody
in core/providers/anthropic/utils.go and both call sites in
core/providers/anthropic/requestbuilder.go at lines 379-384 and 602-607 to pass
or apply cfg.Provider, ensuring native JSON-object fallbacks are stripped when
!ProviderFeatures[cfg.Provider].ServerSideFallback while retaining current
behavior for supported providers.
---
Outside diff comments:
In `@core/providers/anthropic/responses.go`:
- Around line 3438-3446: The chat request conversion in ToAnthropicChatRequest
does not propagate native fallbacks. Mirror the responses conversion by reading
ExtraParams["fallbacks"], assigning it to AnthropicMessageRequest.Fallbacks, and
preserving the existing behavior that triggers the beta header when fallbacks
are present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 80227888-d6a2-45ef-900a-99c806c457bb
📒 Files selected for processing (5)
core/providers/anthropic/requestbuilder.gocore/providers/anthropic/responses.gocore/providers/anthropic/types.gocore/providers/anthropic/utils.gocore/providers/anthropic/utils_test.go
83571c1 to
db9bd25
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/providers/anthropic/responses.go (1)
3315-3334: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winStrip Anthropic-native
fallbacksbefore cross-provider fallback.Params.ExtraParamsis reused on fallback attempts, and providers like Bedrock forwardExtraParamsverbatim, so this raw Anthropic field can reach a non-Anthropic upstream and break the request.core/providers/anthropic/responses.go:3315-3334🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/anthropic/responses.go` around lines 3315 - 3334, Update AnthropicMessageRequest.ToBifrostResponsesRequest so Anthropic-native fallbacks are not retained in Params.ExtraParams when cross-provider fallback requests may reuse it; only forward the native “fallbacks” field for the Anthropic upstream, preventing providers such as Bedrock from receiving it verbatim.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@core/providers/anthropic/responses.go`:
- Around line 3315-3334: Update
AnthropicMessageRequest.ToBifrostResponsesRequest so Anthropic-native fallbacks
are not retained in Params.ExtraParams when cross-provider fallback requests may
reuse it; only forward the native “fallbacks” field for the Anthropic upstream,
preventing providers such as Bedrock from receiving it verbatim.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a138295d-cc1b-44f6-bd0e-a8e3a0bcf9b2
📒 Files selected for processing (8)
core/providers/anthropic/chat.gocore/providers/anthropic/requestbuilder.gocore/providers/anthropic/responses.gocore/providers/anthropic/serversidefallback_test.gocore/providers/anthropic/types.gocore/providers/anthropic/utils.gocore/providers/anthropic/utils_test.gocore/schemas/responses.go
🚧 Files skipped from review as they are similar to previous changes (2)
- core/providers/anthropic/requestbuilder.go
- core/providers/anthropic/utils.go
db9bd25 to
42ad071
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/e2e/api/collections/provider-harness.json`:
- Around line 40994-41044: Update the request model in the test named
“anthropic/claude-fable-5 · native object fallbacks forwarded with
server-side-fallback beta” to use a currently live Anthropic model documented
elsewhere in the harness, such as claude-opus-4-8 or claude-sonnet-5. Keep the
fallback payload and beta-header assertions unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 43d38f3d-ef17-490b-b5e5-935004ed23e8
📒 Files selected for processing (14)
core/providers/anthropic/chat.gocore/providers/anthropic/requestbuilder.gocore/providers/anthropic/responses.gocore/providers/anthropic/serversidefallback_test.gocore/providers/anthropic/types.gocore/providers/anthropic/utils.gocore/providers/anthropic/utils_test.gocore/providers/bedrock/responses.gocore/providers/cohere/responses.gocore/providers/gemini/responses.gocore/providers/openai/responses.gocore/providers/openai/responses_test.gocore/schemas/responses.gotests/e2e/api/collections/provider-harness.json
🚧 Files skipped from review as they are similar to previous changes (5)
- core/providers/anthropic/chat.go
- core/schemas/responses.go
- core/providers/anthropic/responses.go
- core/providers/anthropic/types.go
- core/providers/anthropic/utils_test.go
42ad071 to
b587562
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
core/providers/anthropic/utils.go (1)
504-512: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMinor: inconsistent error handling for the
fallback_credit_tokenstrip.Every other strip in this function wraps the error with descriptive context (
fmt.Errorf("strip raw <field>: %w", err)) and reuses the outererr. This branch shadows the outererrwith a freshvar err errorand returns it unwrapped, losing the "which strip failed" context.♻️ Align with sibling strips
if !features.FallbackCredit { - var err error jsonBody, err = providerUtils.DeleteJSONField(jsonBody, "fallback_credit_token") if err != nil { - return nil, err + return nil, fmt.Errorf("strip raw fallback_credit_token: %w", err) } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/anthropic/utils.go` around lines 504 - 512, Update the fallback_credit_token removal branch in the surrounding function to reuse the existing outer err variable instead of declaring a shadowing local error, and wrap DeleteJSONField failures with descriptive context consistent with the sibling field-stripping branches before returning.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@core/providers/anthropic/utils.go`:
- Around line 504-512: Update the fallback_credit_token removal branch in the
surrounding function to reuse the existing outer err variable instead of
declaring a shadowing local error, and wrap DeleteJSONField failures with
descriptive context consistent with the sibling field-stripping branches before
returning.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: f0a88200-000a-49f6-bd7b-4239e44ac7f1
📒 Files selected for processing (14)
core/providers/anthropic/chat.gocore/providers/anthropic/requestbuilder.gocore/providers/anthropic/responses.gocore/providers/anthropic/serversidefallback_test.gocore/providers/anthropic/types.gocore/providers/anthropic/utils.gocore/providers/anthropic/utils_test.gocore/providers/bedrock/responses.gocore/providers/cohere/responses.gocore/providers/gemini/responses.gocore/providers/openai/responses.gocore/providers/openai/responses_test.gocore/schemas/responses.gotests/e2e/api/collections/provider-harness.json
🚧 Files skipped from review as they are similar to previous changes (10)
- core/providers/anthropic/chat.go
- core/providers/bedrock/responses.go
- core/providers/openai/responses.go
- core/providers/openai/responses_test.go
- tests/e2e/api/collections/provider-harness.json
- core/providers/cohere/responses.go
- core/schemas/responses.go
- core/providers/anthropic/requestbuilder.go
- core/providers/anthropic/responses.go
- core/providers/anthropic/types.go

Summary
Anthropic's native server-side fallback feature (
server-side-fallback-2026-06-01) uses a"fallbacks"request field containing JSON objects ({"model": "..."}) — the same wire key that Bifrost uses for cross-provider fallback strings ("provider/model"). Previously, Bifrost unconditionally deleted the entire"fallbacks"field before forwarding requests to Anthropic, which broke native server-side fallbacks. This PR disambiguates the two by shape, preserving native fallback objects while still stripping Bifrost cross-provider strings.Changes
[]stringonAnthropicMessageRequest.Fallbackswith[]AnthropicFallbackEntry, a union type that unmarshals JSON strings as Bifrost cross-provider fallbacks and JSON objects as Anthropic native server-side fallbacks.AnthropicNativeFallbackstruct representing one entry of Anthropic's native"fallbacks"list, with optionalmax_tokensandthinkingoverrides.DeleteJSONField("fallbacks")call in bothBuildAnthropicResponsesRequestBodyandBuildAnthropicChatRequestBodywithstripBifrostFallbacksFromBody, which removes only string entries and deletes the field entirely when no native objects remain.bifrostFallbackModels()andnativeFallbacks()helpers onAnthropicMessageRequestto separate the two entry kinds cleanly.ToBifrostResponsesRequestto route native fallback objects intoExtraParams["fallbacks"]for verbatim forwarding, while Bifrost strings continue to populateBifrostResponsesRequest.Fallbacks.ToAnthropicResponsesRequestto reconstruct the typedFallbacksfield fromExtraParams["fallbacks"]when native entries are present.ServerSideFallback booltoProviderFeatureSupport, enabled only for the Anthropic provider (not Bedrock, Vertex, or Azure), and wired it intoAddMissingBetaHeadersToContextso theserver-side-fallback-2026-06-01beta header is auto-injected when native fallbacks are present.AnthropicServerSideFallbackBetaHeaderPrefixin the known-prefix lists used for beta header deduplication and provider-feature gating.Type of change
Affected areas
How to test
go test ./core/providers/anthropic/...Key test cases added:
TestAnthropicFallbackEntry_UnmarshalJSON— verifies string vs. object dispatch and round-trip marshalling.TestAnthropicMessageRequest_NativeFallbacksParse— regression for the "Invalid JSON" error when a request carries native{"model": ...}fallback objects.TestToBifrostResponsesRequest_FallbacksRouting— verifies native objects go toExtraParamsand Bifrost strings go toFallbacks.TestAddMissingBetaHeadersToContext_ServerSideFallback— verifies the beta header is injected on Anthropic and suppressed on Vertex.TestBuildAnthropicResponsesRequestBody_NativeFallbacks— end-to-end body assembly for both raw-passthrough and typed paths, covering native preservation, Bifrost stripping, and beta header injection.Breaking changes
The
Fallbacks []stringfield onAnthropicMessageRequestis an internal type not part of the public Bifrost API surface. Existing Bifrost cross-provider fallback behaviour is unchanged.Security considerations
No auth, secrets, or PII implications. The change only affects how the
"fallbacks"JSON field is forwarded to the Anthropic API.Checklist
docs/contributing/README.mdand followed the guidelines