{"record":{"id":"72d030322fade96f","repo":"alibaba/open-code-review","slug":"bedrock-has-no-access-enabled-for-model-q-s","errorCode":null,"errorMessage":"bedrock has no access enabled for model %q (%s): %w\n  model access is granted per account and per region in the Bedrock console; an IAM policy alone does not enable it","messagePattern":"bedrock has no access enabled for model %q \\((.+?)\\): %w\n  model access is granted per account and per region in the Bedrock console; an IAM policy alone does not enable it","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/client.go","lineNumber":1112,"sourceCode":"\tmsg := err.Error()\n\twhere := c.bedrockWhere()\n\n\t// Order matters here, and the two AccessDenied shapes are why: Bedrock\n\t// answers both \"your IAM policy forbids this\" and \"this account has not\n\t// enabled the model\" with AccessDeniedException, and the fixes have nothing\n\t// in common. The specific wording is matched before the generic code.\n\tswitch {\n\t// First: the bearer-token path produces this even when credentials are\n\t// otherwise valid, so a later \"denied\" branch would mislabel it.\n\tcase strings.Contains(msg, \"Invalid API Key format\"):\n\t\tif os.Getenv(\"AWS_BEARER_TOKEN_BEDROCK\") != \"\" {\n\t\t\treturn fmt.Errorf(\"bedrock rejected the token in AWS_BEARER_TOKEN_BEDROCK (%s): %w\\n\"+\n\t\t\t\t\"  unset that variable to sign requests with SigV4 instead\", where, err)\n\t\t}\n\t\treturn fmt.Errorf(\"bedrock rejected an API-key header rather than a signature (%s): %w\\n\"+\n\t\t\t\"  no api_key applies to bedrock; this means a bearer token reached the request, not that a key is missing\", where, err)\n\tcase strings.Contains(msg, \"don't have access to the model\"):\n\t\treturn fmt.Errorf(\"bedrock has no access enabled for model %q (%s): %w\\n\"+\n\t\t\t\"  model access is granted per account and per region in the Bedrock console; an IAM policy alone does not enable it\", model, where, err)\n\tcase strings.Contains(msg, \"model identifier is invalid\"),\n\t\tstrings.Contains(msg, \"inference profile\") && strings.Contains(msg, \"not found\"):\n\t\treturn fmt.Errorf(\"bedrock rejected model %q (%s): %w\\n\"+\n\t\t\t\"  run `aws bedrock list-inference-profiles%s` to see what this account offers — IDs are account- and region-scoped, and a version suffix such as -v1:0 is invalid for the newer families\",\n\t\t\tmodel, where, err, listProfilesRegionArg(c.awsRegion))\n\t// Specific credential codes only. A bare \"expired\" would also claim an\n\t// expired TLS certificate is an SSO problem.\n\tcase strings.Contains(msg, \"ExpiredToken\"), strings.Contains(msg, \"ExpiredTokenException\"),\n\t\tstrings.Contains(msg, \"SSOProviderInvalidToken\"), strings.Contains(msg, \"InvalidGrantException\"),\n\t\tstrings.Contains(msg, \"NoCredentialProviders\"), strings.Contains(msg, \"failed to refresh cached credentials\"):\n\t\treturn fmt.Errorf(\"bedrock could not authenticate: AWS credentials are expired or unavailable (%s): %w\\n\"+\n\t\t\t\"  run `aws sso login%s`, or refresh whichever credential source this profile uses\", where, err, ssoLoginProfileArg(c.awsProfile))\n\t// \"not authorized to invoke this API operation\" is IAM's own wording, so it\n\t// belongs here rather than in the model-access branch above: the fix is a\n\t// policy change, not a console toggle.\n\tcase strings.Contains(msg, \"AccessDenied\"),\n\t\tstrings.Contains(msg, \"not authorized to invoke this API operation\"):","sourceCodeStart":1094,"sourceCodeEnd":1130,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/client.go#L1094-L1130","documentation":"explainError (internal/llm/client.go:1112) matches Bedrock's 'don't have access to the model' wording, which the service sends when the AWS account has not enabled model access for that model. The rewrite makes clear this is an account/region-level console setting, NOT something an IAM policy can fix — a common misdiagnosis.","triggerScenarios":"Invoking a Bedrock model (e.g. anthropic.claude-*) in a region where the account never subscribed/enabled that model; service returns the access-denied wording and this branch fires.","commonSituations":"New AWS account that has not requested Claude access; using a model available in us-east-1 from a freshly-used ap-northeast-1 account where access was never granted; org switched regions without re-enabling models.","solutions":["Open the AWS Bedrock console → Model access, select the region, and request/enable access for the model","Wait for the access grant to complete (usually minutes; some models longer)","Re-run after confirmation — check with `aws bedrock list-foundation-models --region <region>` that the model is offered and enabled","If using a cross-account role, enable model access in the account that actually owns the credentials"],"exampleFix":"// before\naws bedrock invoke-model --model-id anthropic.claude-sonnet-4-20250514 ...  # AccessDenied: don't have access\n// after\n# Console: Bedrock → Model access → Claude Sonnet 4 → Request/Enable\naws bedrock invoke-model --model-id anthropic.claude-sonnet-4-20250514 ...  # succeeds","handlingStrategy":"fallback","validationCode":"out, err := exec.Command(\"aws\", \"bedrock\", \"list-foundation-models\",\n    \"--region\", region,\n    \"--by-provider\", \"anthropic\").Output()\nif err != nil || len(out) == 0 {\n    return errors.New(\"model access not enabled for Anthropic models in this region — enable in the Bedrock console\")\n}","typeGuard":null,"tryCatchPattern":"_, err := cl.Call(ctx, messages)\nif err != nil && strings.Contains(err.Error(), \"no access enabled for model\") {\n    return fmt.Errorf(\"enable the model in Bedrock console → Model access for %s, then retry: %w\", region, err)\n}","preventionTips":["Enable model access in the Bedrock console for every region you deploy in","Re-check access after creating a new AWS account or switching regions","Use `aws bedrock list-foundation-models` in CI preflight","Remember IAM policies cannot substitute for console model-access grants"],"tags":["aws","bedrock","model-access","permissions"],"backgroundTag":"bedrock-model-access-disabled","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}