Skip to content

[V2] Bedrock: bare Sonnet 5.5 / Haiku 5.5 (and Llama 4, Palmyra) IDs are offered but only work as inference profiles #54485

Closed

Description

@kimnamu

Description

Thanks @rekram1-node for #48078 and #48081: hiding the profile-only bare IDs cleaned up the V2 Bedrock picker, and the eu-west-2 note made the 4.6 exception easy to follow.

Claude Sonnet 5.5 (09-28) and Haiku 5.5 (10-07) arrived after that list, and their bare catalog IDs fail the same way. V2 sends the ID as-is (packages/ai/src/protocols/bedrock-converse.ts:552, :887), and Bedrock answers every call with on-demand throughput isn't supported. Four older Converse-routed IDs do the same: Llama 4 Maverick/Scout and Palmyra X4/X5.

Live Converse, 16-token probe:

ID bare us. profile
anthropic.claude-sonnet-5-5 ValidationException (us-east-1, eu-west-2, ap-northeast-2) 200
anthropic.claude-haiku-5-5 ValidationException (us-east-1, eu-west-2, ap-southeast-1) 200
meta.llama4-maverick-17b-instruct-v1:0 ValidationException (us-east-1) 200
meta.llama4-scout-17b-instruct-v1:0 ValidationException (us-east-1) 200
writer.palmyra-x4-v1:0 ValidationException (us-west-2) 200
writer.palmyra-x5-v1:0 ValidationException (us-west-2) 200
anthropic.claude-opus-5-5 (control) 200 in eu-west-2
ValidationException: Invocation of model ID anthropic.claude-sonnet-5-5 with on-demand throughput isn’t supported. Retry your request with the ID or ARN of an inference profile that contains this model.

list_foundation_models in the 17 default regions agrees: these six are INFERENCE_PROFILE only wherever they are listed. Opus 5.5 is ON_DEMAND in eu-west-2 like the 4.6 pair, so it should stay visible.

The fix is six rows in BEDROCK_PROFILE_ONLY_IDS (packages/core/src/plugin/models-dev.ts). I have it on a branch with the checks below and can open the PR.

Patch and notes
-// Opus/Sonnet 4.6 support in-region calls in eu-west-2 and must remain available.
+// Opus/Sonnet 4.6 and Opus 5.5 support in-region calls in eu-west-2 and must remain available.
@@
   "anthropic.claude-haiku-4-5-20251001-v1:0",
+  "anthropic.claude-haiku-5-5",
@@
   "anthropic.claude-sonnet-5",
+  "anthropic.claude-sonnet-5-5",
   "deepseek.r1-v1:0",
+  "meta.llama4-maverick-17b-instruct-v1:0",
+  "meta.llama4-scout-17b-instruct-v1:0",
   "mistral.pixtral-large-2502-v1:0",
+  "writer.palmyra-x4-v1:0",
+  "writer.palmyra-x5-v1:0",
 ]
  • Bare IDs that models.dev routes to Mantle (GPT-5.x/6.x, Grok, gpt-oss, Gemma 4) are valid as they are and stay.
  • Not changed, for your call: bare anthropic.claude-opus-5 returned 200 in ap-northeast-2 and bare anthropic.claude-sonnet-5 in eu-west-2. Both are ON_DEMAND there per list_foundation_models, so by the 4.6 rule they could come off the list.
  • 1.x prefixes claude IDs at request time, so this looks V2-only for Claude.

Plugins

None

OpenCode version

dev @ e31136b (2.0.26)

Steps to reproduce

  1. Call Bedrock Converse (boto3) with modelId="anthropic.claude-sonnet-5-5" in us-east-1: ValidationException above. us.anthropic.claude-sonnet-5-5 returns 200.
  2. On dev, run the current models.dev catalog through ModelsDevPlugin: all six bare IDs are in Model.available() for amazon-bedrock, with no Mantle override, so they go to Converse unchanged.

Screenshot and/or share link

Not a UI issue; the Bedrock error is quoted above.

Operating System

macOS 26

Terminal

Not terminal-specific

Activity

  1. opencode-agent commented on Oct 11, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report and the probe table. I could confirm the OpenCode side on dev @ e31136b, which is also the latest dev.

    I ran the current models.dev catalog through ModelsDevPlugin (the test is below):

    • anthropic.claude-sonnet-5-5, anthropic.claude-haiku-5-5, meta.llama4-maverick-17b-instruct-v1:0, meta.llama4-scout-17b-instruct-v1:0, writer.palmyra-x4-v1:0 and writer.palmyra-x5-v1:0 are all offered for amazon-bedrock.
    • They use the Converse package and keep the bare model ID, because none of them is in BEDROCK_PROFILE_ONLY_IDS.
    • As expected, us.anthropic.claude-sonnet-5-5 and bare anthropic.claude-opus-5-5 stay available, and anthropic.claude-sonnet-5 (already on the list) is hidden.

    The sandbox has no AWS credentials, so I couldn't trigger the Bedrock ValidationException myself. That part relies on your probes.

    Until this changes, the us./eu. profile IDs work as a workaround.

    Related: #48078 added the list. #52046 deals with Sonnet 5.5 Converse request bodies, which is a separate problem.

    To run the test: copy it into packages/core/test/plugin/, download https://models.dev/api.json, then run MODELS_DEV_JSON=<path> bun test test/plugin/repro-54485.test.ts from packages/core.

    Reproduction script (repro-54485.test.ts)
    // Repro for anomalyco/opencode#54485: bare Bedrock IDs that only work as inference
    // profiles are still materialized by ModelsDevPlugin from the live models.dev catalog.
    // Needs MODELS_DEV_JSON=<path to https://models.dev/api.json download>.
    import { describe, expect } from "bun:test"
    import { Effect, Layer } from "effect"
    import { Integration } from "@opencode/core/integration"
    import { AppNodeBuilder } from "@opencode/core/effect/app-node-builder"
    import { LayerNode } from "@opencode/util/effect/layer-node"
    import { Bus } from "@opencode/core/bus"
    import { Location } from "@opencode/core/location"
    import { Model } from "@opencode/core/model"
    import { ModelsDev } from "@opencode/core/models-dev"
    import { ModelsDevPlugin } from "@opencode/core/plugin/models-dev"
    import { Provider } from "@opencode/core/provider"
    import { AbsolutePath } from "@opencode/core/schema"
    import { location } from "../fixture/location"
    import { testEffect } from "../lib/effect"
    import { providerHost, host, integrationHost } from "./host"
    
    const layer = AppNodeBuilder.build(LayerNode.group([Provider.node, Model.node, Integration.node, Bus.node]), [
      Location.node.replace(Layer.succeed(Location.Service, Location.Service.of(location({ directory: AbsolutePath.make(import.meta.dir) })))),
    ])
    const it = testEffect(layer)
    const catalog = AppNodeBuilder.build(ModelsDev.node, [
      ModelsDev.node.replace(ModelsDev.configured({ file: process.env.MODELS_DEV_JSON!, fetch: false })),
    ])
    
    const ids = [
      "anthropic.claude-sonnet-5-5",
      "anthropic.claude-haiku-5-5",
      "meta.llama4-maverick-17b-instruct-v1:0",
      "meta.llama4-scout-17b-instruct-v1:0",
      "writer.palmyra-x4-v1:0",
      "writer.palmyra-x5-v1:0",
      // controls
      "us.anthropic.claude-sonnet-5-5",
      "anthropic.claude-opus-5-5",
      "anthropic.claude-sonnet-5",
    ]
    
    describe("#54485", () => {
      it.effect("bare profile-only Bedrock IDs", () =>
        Effect.gen(function* () {
          const providers = yield* Provider.Service
          const models = yield* Model.Service
          const integrations = yield* Integration.Service
          yield* ModelsDevPlugin.effect(host({ provider: providerHost(providers), integration: integrationHost(integrations) }))
          yield* providers.transform((editor) => {
            for (const record of editor.list()) editor.update(record.provider.id, (p) => { p.activation = "enabled" })
          })
          const result: Record<string, string> = {}
          for (const id of ids) {
            const m = yield* models.get(Provider.ID.make("amazon-bedrock"), Model.ID.make(id))
            result[id] = m ? `OFFERED package=${m.package} modelID=${m.modelID ?? m.id}` : "hidden"
          }
          console.log(JSON.stringify(result, null, 2))
          for (const id of ids.slice(0, 6)) expect(result[id]).toBe("hidden")
        }).pipe(Effect.provide(catalog)),
      )
    })

    Run it: bun repro-54485.test.ts

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions