Repository navigation
Description
Description
When a Bedrock model's API id is an application inference profile ARN, the generated effort variants are built in Amazon Nova format even though the profile is backed by a Claude model. Bedrock returns a 400 for reasoningConfig on a Claude model.
This is the v2 counterpart of #53751, which was closed as won't-fix for v1 (v1 only gets critical fixes) with a request to check v2.
An ARN looks like arn:aws:bedrock:<region>:<account>:application-inference-profile/<id>. It contains no model name, so any check that reads the model name from the id will misidentify it.
Cause
Read from the v2 branch at 119cb15d1d (2.0.24). I have not yet run @opencode/cli against a real profile, so this comes from reading the code.
packages/core/src/variant.ts:410-412:bedrockConversesetsclaude = modelID(model).includes("anthropic"). For an ARN this is false, so the Claude shape (thinking+output_config: { effort }) is replaced byreasoningConfig: { type: "enabled", maxReasoningEffort }.packages/core/src/variant.ts(claudeInfo): reads the Claude family and version from the id. For an ARN the version isNaN, so the model is treated as a new one (adaptive thinking). That is wrong for Claude 4.5 and older, which need a token budget.packages/core/src/config/plugin/provider.ts:151: variants are only auto-generated when none are configured. That is why declaringvariantsby hand avoids the problem.packages/ai/src/protocols/utils/claude-model.ts:claudeVersionalso reads the id. Thecompatibility.supportsThinkingBlockBindingoverride covers this one.
The model already has a family field, and the config accepts it, but the Bedrock variant generator never reads it.
Expected behaviour
Claude behaviour whenever the model is known to be Claude, for example when family is set to a Claude family, whatever the API id looks like.
Suggested fix
Treat the model as Claude when model.family contains "claude", in bedrockConverse and claudeInfo. Add a test in the variant tests using an ARN id with family set. Happy to send a PR if that direction is fine.
Workaround
Declare variants on the model with body.additionalModelRequestFields = { thinking: { type: "adaptive" }, output_config: { effort } }.
Why it matters
Application inference profiles are the supported way to get per-team Bedrock cost and usage tracking, so this blocks that setup.
Related
- Bedrock application inference profile ARNs: reasoning variants fail and the wrong system prompt is used #53751 (v1 report)
- [BUG] Bedrock Claude application inference profile reasoning variants send invalid payload #31749, AWS Bedrock Claude models with Inference Profile ARNs fail to trigger Extended Thinking (Reasoning) #10611 (earlier reports of the same reasoning payload error)
- V2: bring Bedrock Converse native auth and config to parity #34997 (Bedrock Converse parity in v2)
OpenCode version
2.0.24 (@opencode/cli, source read from the v2 branch)
Steps to reproduce
- Configure a Bedrock model whose API id is an application inference profile ARN backed by a Claude model, with
familyset to a Claude family. - Let variants auto-generate (do not set
variants). - Select any effort variant, such as
high, and send a message. - Expected: the request carries
thinkingandoutput_config. Actual (from reading the code): it carriesreasoningConfig, which Bedrock rejects with a 400.
Activity
github-actions commentedon Oct 7, 2026
This issue appears to overlap with existing Bedrock Claude inference-profile reasoning reports. Please check:
opencode-agent commentedon Oct 7, 2026
Thanks for the detailed report. I could reproduce this on
@opencode/cli2.0.24.Setup: an
amazon-bedrockmodel whosemodelIDis an application inference profile ARN (arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123), withfamily: "claude-sonnet"and novariants. I pointedbaseURLat a local server that records requests, then ranopencode2 run -m 'amazon-bedrock/team-sonnet#high' "hello".The Converse request for the ARN carried
additionalModelRequestFields: { reasoningConfig: { type: "enabled", maxReasoningEffort: "high" } }, not the Claudethinking/output_configshape. A regularus.anthropic.claude-sonnet-4-5…id gets the Claude shape, so the configuredfamilyis not taken into account. The variant code is unchanged on the currentv2branch. Until this is addressed, declaringvariantsby hand, as you describe, avoids it.gillespied commentedon Oct 7, 2026
Thanks for reproducing this.
I have a one-line fix with a test on a fork branch:
bedrockConverseinpackages/core/src/variant.tsalso treats the model as Claude whenfamilycontains "claude". The branch is https://github.com/gillespied/opencode/tree/fix/bedrock-arn-claude-variants, based onv2at119cb15. The new test invariant.test.tsfails without the change (Nova spelling for an ARN id) and passes with it. I have only checked the variant generator, not a real profile, so your end-to-end repro above is the better check. Happy to open a PR if that's useful, or you can take it from the branch.Correction to the issue text: I suggested changing
claudeInfotoo, but a family name carries no version, so that wouldn't help. Claude 4.5 and older behind an ARN still need explicitvariants.opencode-agent commentedon Oct 7, 2026
You can fix this in config today, without a code change. Use the Bedrock catalog id of the model your profile wraps as the model key, and put the ARN in
modelID:{ "providers": { "amazon-bedrock": { "models": { "us.anthropic.claude-sonnet-4-5-20250929-v1:0": { "modelID": "arn:aws:bedrock:<region>:<account>:application-inference-profile/<id>" } } } } }Then select it as
amazon-bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0#high.Why this works: if a configured model's key (or
modelID) matches a catalog model, it inherits that catalog entry, including the variants already generated from the real Claude id. Variants are only regenerated frommodelIDwhen nothing in the catalog matches. That is the case you hit, where the ARN gets misread as a non-Claude model.modelIDstill decides what gets sent, so requests go to your profile.I checked this on 2.0.24 against a real application inference profile backed by Sonnet 4.5:
modelID,family: "claude-sonnet",#high: fails withreasoningConfig: Extra inputs are not permitted. This reproduces your report.modelID,#high: works, and reasoning comes back.The provided model identifier is invalid. So the profile ARN is what actually gets called.If you'd rather keep your own key, declaring
variantsyourself, as in your workaround, also works.rekram1-node commentedon Oct 8, 2026
recommend u solve it this way^ for now. I'll look at bedrock im less familiar with these unknown deployments.
andrewcarson commentedon Oct 8, 2026
Keying the model by its exact catalog ID and putting the ARN in
modelIDfixes the reasoning variants and inherits the right limits. It has one downside with application inference profiles onv2: prompt caching turns off.Bedrock Converse decides whether to emit
cachePointblocks from the model ID.BedrockCache.breakpoints(request.model.id)setssupportedonly when the ID includesanthropic.claude-(packages/ai/src/protocols/utils/bedrock-cache.ts). The same string is also sent to the API asmodelId.An application inference profile ARN is opaque (
…:application-inference-profile/abc123) and has no Claude name in it, so no checkpoints are added.The model and reasoning work, but every request is uncached. That costs more and is slower.
I have a fix on a branch. It adds an
arnsetting to the Bedrock Converse provider. The model keeps its real ID, and the ARN goes insettings:Here the property name is the real model ID. With a custom name, set
modelIDto the real ID as well:Catalog inheritance, variants and cache detection all use the real ID. opencode sends the ARN to Bedrock as the request's
modelId.florislw commentedon Oct 15, 2026
We hit this too. Caching is off for our Claude application inference profiles on v2, so we're sticking with v1 for now.
Looks like a regression: v1 fixed the same thing in #9838.
@andrewcarson, any chance you could open a PR for the
settings.arnchange? Would be great to have.florislw commentedon Oct 15, 2026
Another option, possibly smaller than
settings.arn: a modelcompatibilityflag for Bedrock cache points, like the onessupportsThinkingBlockBindingandsupportsEffortUpdatesalready have for their checks. The TODO inanthropic-messages.tsabout moving capability heuristics intocompatibilityseems to point the same way.Happy to open a PR if that sounds right to you.
rekram1-node commentedon Oct 15, 2026
I'll take a look sorry about that yall