alibaba/open-code-review · error
%s cannot be %q: bedrock derives its host from aws_region an
Error message
%s cannot be %q: bedrock derives its host from aws_region and signs with the AWS credential chain, so it has no use for a url or a token; configure it as a provider instead ("provider": "bedrock") What it means
errBedrockNotConfigurable explains why the url+token configuration strategies (OCR_* env vars and the legacy llm config block) reject the bedrock protocol. Bedrock derives its host from aws_region and signs requests with the AWS credential chain, so a single-HTTP-endpoint description carrying only a url and token has no place to express a region or profile, and its url/token fields would be silently ignored. The resolver refuses the value at the point it is read rather than switching transports and dropping the rest of the block.
Source
Thrown at internal/llm/resolver.go:242
}
if sec < 0 {
return 0, fmt.Errorf("timeout_sec must be non-negative, got %d", sec)
}
// Guard against overflow: time.Duration is int64 nanoseconds.
maxSec := int64(math.MaxInt64 / int64(time.Second))
if int64(sec) > maxSec {
return 0, fmt.Errorf("timeout_sec %d overflows time.Duration (max %d)", sec, maxSec)
}
return time.Duration(sec) * time.Second, nil
}
// errBedrockNotConfigurable explains why the two url+token strategies reject the
// bedrock protocol. Both describe a single HTTP endpoint and carry no place for
// a region or a profile, and bedrock uses neither the url nor the token they do
// carry. Accepting the value would switch transports and silently ignore the
// rest of the block, so it is refused at the point it is read.
func errBedrockNotConfigurable(key string) error {
return fmt.Errorf("%s cannot be %q: bedrock derives its host from aws_region and signs with the AWS credential chain, so it has no use for a url or a token; configure it as a provider instead (\"provider\": \"bedrock\")",
key, ProtocolAnthropicBedrock)
}
// tryOCREnv reads OCR-specific environment variables.
func tryOCREnv(modelOverride string) (ResolvedEndpoint, bool, error) {
url := os.Getenv(envOCRLLMURL)
token := os.Getenv(envOCRLLMToken)
model := os.Getenv(envOCRLLMModel)
if modelOverride != "" {
model = modelOverride
}
if url == "" || token == "" || model == "" {
return ResolvedEndpoint{}, false, nil
}
// OCR_LLM_PROTOCOL (normalized) wins over OCR_USE_ANTHROPIC when set.
protocol := ""
if raw := strings.TrimSpace(os.Getenv(envOCRLLMProtocol)); raw != "" {View on GitHub (pinned to 5cf97d0d15)
Solutions
- Remove the bedrock protocol value from the url+token strategy (unset OCR_LLM_PROTOCOL or delete the protocol line in the llm block)
- Configure bedrock as a provider instead: set "provider": "bedrock" and add a matching entry under "providers" with aws_region (and optionally aws_profile)
- Keep OCR_LLM_URL/OCR_LLM_TOKEN only for direct-HTTP protocols such as anthropic or openai
Example fix
// before
export OCR_LLM_URL=https://bedrock-runtime.us-east-1.amazonaws.com
export OCR_LLM_TOKEN=aws-token
export OCR_LLM_PROTOCOL=anthropic-bedrock
// after — ~/.config/ocr/config.json
{
"provider": "bedrock",
"model": "us.anthropic.claude-sonnet-4-20250514-v1:0",
"providers": { "bedrock": { "aws_region": "us-east-1" } }
} Defensive patterns
Strategy: validation
Validate before calling
proto := strings.TrimSpace(os.Getenv("OCR_LLM_PROTOCOL"))
if proto != "" && strings.EqualFold(proto, "anthropic-bedrock") {
if os.Getenv("OCR_LLM_URL") != "" || os.Getenv("OCR_LLM_TOKEN") != "" {
return errors.New("bedrock must be configured as a provider (\"provider\": \"bedrock\"), not via url+token env vars")
}
} Type guard
func isURLTokenProtocol(p string) bool {
switch p {
case "anthropic", "openai", "openai-responses":
return true
}
return false
} Prevention
- Never put bedrock under a url+token strategy; reserve OCR_LLM_URL/OCR_LLM_TOKEN for hosted HTTP endpoints
- Configure AWS-region backends via "provider": "bedrock" with aws_region/aws_profile
- Keep protocol selection (OCR_LLM_PROTOCOL) away from ambient-auth providers
When it happens
Trigger: Setting OCR_LLM_PROTOCOL=anthropic-bedrock while OCR_LLM_URL/OCR_LLM_TOKEN/OCR_LLM_MODEL are set (tryOCREnv), or putting "protocol": "anthropic-bedrock" inside the legacy url+token llm config block (tryLegacyLlmConfig). Both strategies describe one HTTP endpoint and carry no region/profile field.
Common situations: A developer who previously reached Bedrock through an AWS SDK endpoint URL pastes that URL and a token into the OCR env vars; or copies an llm block written for a hosted Anthropic endpoint and flips the protocol to bedrock expecting it to just work.
Related errors
- bedrock: could not load AWS configuration: %w bedrock uses
- bedrock: no AWS region resolved set AWS_REGION, or give th
- bedrock rejected model %q (%s): %w run `aws bedrock list-i
- llm.protocol cannot be %q: bedrock derives its host from aws
- %s does not apply to provider %q: aws_region and aws_profile
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/685765d36651428c.
Report an issue: GitHub.