alibaba/open-code-review · error
cannot be : bedrock derives its host from aws_region and…
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.
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
- bedrock: no AWS region resolved set AWS_REGION, or give…
- bedrock rejected model
- bedrock could not authenticate: AWS credentials are expired…
- bedrock denied access to model
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/685765d36651428c.
Report an issue: GitHub.
Appendix: 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)