-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Open
Description
Bug: AWS Bedrock fails in Asia Pacific regions with "invalid model identifier" error
Description
When using OpenCode with AWS Bedrock in Asia Pacific regions (e.g., ap-southeast-2), OpenCode attempts to use EU inference profile models (eu.anthropic.claude-haiku-4-5-20251001-v1:0) which don't exist in these regions, causing "The provided model identifier is invalid" errors.
Environment
- OpenCode Version: Latest (main branch)
- Region:
ap-southeast-2(Sydney, Australia) - AWS Profile: Configured with valid credentials
- Provider:
amazon-bedrock - Configuration:
{ "provider": { "amazon-bedrock": { "options": { "region": "ap-southeast-2", "profile": "bedrock-user" } } } }
Steps to Reproduce
- Configure AWS Bedrock provider with
ap-southeast-2region - Configure oh-my-opencode agents to use Bedrock models:
{ "agents": { "build": { "model": "amazon-bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0" } } } - Run any OpenCode command that triggers the title generation agent
- Observe error logs showing EU model being used
Expected Behavior
OpenCode should:
- Detect the
ap-southeast-2region - Select appropriate models for that region:
- Direct models:
anthropic.claude-haiku-4-5-20251001-v1:0 - Global profiles:
global.anthropic.claude-haiku-4-5-20251001-v1:0 - AU profiles:
au.anthropic.claude-haiku-4-5-20251001-v1:0(for Australia)
- Direct models:
Actual Behavior
OpenCode incorrectly selects EU inference profile models:
ERROR service=llm providerID=amazon-bedrock modelID=eu.anthropic.claude-haiku-4-5-20251001-v1:0
error={"error":{"statusCode":400,"responseBody":"{\"message\":\"The provided model identifier is invalid.\"}"}}
The API correctly calls the ap-southeast-2 endpoint but with an invalid EU model ID:
https://bedrock-runtime.ap-southeast-2.amazonaws.com/model/eu.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse-stream
Root Cause
The bug is in the getSmallModel() function in /packages/opencode/src/provider/provider.ts (lines 1174-1195).
Problem 1: Incomplete Prefix List (Line 1175)
const crossRegionPrefixes = ["global.", "us.", "eu."] // ❌ Missing "au.", "apac.", "jp."This doesn't match the complete list used in getModel() at line 243:
const crossRegionPrefixes = ["global.", "us.", "eu.", "jp.", "apac.", "au."] // ✅Problem 2: Region Check Only for US/EU (Line 1188)
if (regionPrefix === "us" || regionPrefix === "eu") { // ❌ Ignores all other regions!
const regionalMatch = candidates.find((m) => m.startsWith(`${regionPrefix}.`))
if (regionalMatch) return getModel(providerID, regionalMatch)
}For ap-southeast-2:
regionPrefix="ap"(fromregion.split("-")[0])- Condition evaluates to
false - Regional model selection is completely skipped
Proposed Fix
Option 1: Add AP Region Support (Recommended)
if (providerID === "amazon-bedrock") {
const crossRegionPrefixes = ["global.", "us.", "eu.", "jp.", "apac.", "au."] // Add missing prefixes
const candidates = Object.keys(provider.models).filter((m) => m.includes(item))
// 1. Try global prefix (works everywhere)
const globalMatch = candidates.find((m) => m.startsWith("global."))
if (globalMatch) return getModel(providerID, globalMatch)
// 2. Try regional prefix
const region = provider.options?.region
if (region) {
let regionPrefix = region.split("-")[0]
// Map region prefixes to inference profile prefixes
if (regionPrefix === "ap") {
if (["ap-southeast-2", "ap-southeast-4"].includes(region)) {
regionPrefix = "au" // Australia regions
} else if (region === "ap-northeast-1") {
regionPrefix = "jp" // Tokyo region
} else {
regionPrefix = "apac" // Other APAC regions
}
}
if (["us", "eu", "au", "jp", "apac"].includes(regionPrefix)) {
const regionalMatch = candidates.find((m) => m.startsWith(`${regionPrefix}.`))
if (regionalMatch) return getModel(providerID, regionalMatch)
}
}
// 3. Try unprefixed model
const unprefixed = candidates.find((m) => !crossRegionPrefixes.some((p) => m.startsWith(p)))
if (unprefixed) return getModel(providerID, unprefixed)
}Option 2: Fallback to Global for Unsupported Regions (Simpler)
if (regionPrefix === "us" || regionPrefix === "eu") {
const regionalMatch = candidates.find((m) => m.startsWith(`${regionPrefix}.`))
if (regionalMatch) return getModel(providerID, regionalMatch)
} else {
// For other regions, prefer global profiles
const globalMatch = candidates.find((m) => m.startsWith("global."))
if (globalMatch) return getModel(providerID, globalMatch)
}Additional Context
- The main
getModel()function (lines 240-320) correctly handles AP regions with properau.,jp., andapac.prefix mapping - The inconsistency is only in
getSmallModel()used for background tasks like title generation - All AWS Bedrock tests in
/test/provider/amazon-bedrock.test.tsuse onlyus-east-1andeu-west-1regions, which is why this bug wasn't caught
Impact
- Affected regions: All Asia Pacific regions (
ap-*), Japan (ap-northeast-1), and potentially other non-US/EU regions - Affected users: Anyone using AWS Bedrock outside US/EU regions
- Workaround: Remove oh-my-opencode plugin (OpenCode falls back to Anthropic API)
Test Coverage Suggestion
Add test cases for AP regions in amazon-bedrock.test.ts:
test("Bedrock: getSmallModel works in ap-southeast-2 region", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
provider: {
"amazon-bedrock": {
options: {
region: "ap-southeast-2",
},
},
},
}),
)
},
})
await Instance.provide({
directory: tmp.path,
init: async () => {
Env.set("AWS_PROFILE", "default")
},
fn: async () => {
const smallModel = await Provider.getSmallModel("amazon-bedrock")
expect(smallModel).toBeDefined()
// Should use global. or au. prefix, NOT eu.
expect(smallModel?.id).toMatch(/^(global\.|au\.|anthropic\.)/)
expect(smallModel?.id).not.toMatch(/^eu\./)
},
})
})Related Code
- Bug location:
/packages/opencode/src/provider/provider.ts:1147-1211(getSmallModel()) - Working reference:
/packages/opencode/src/provider/provider.ts:240-320(getModel()- correctly handles AP regions) - Tests:
/packages/opencode/test/provider/amazon-bedrock.test.ts(missing AP region test coverage)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels