alibaba/open-code-review · error

llm.protocol cannot be %q: bedrock derives its host from aws

Error message

llm.protocol cannot be %q: bedrock derives its host from aws_region and signs with the AWS credential chain, so it has no use for llm.url or llm.auth_token; run `ocr config set provider bedrock` instead

What it means

Setting llm.protocol to anthropic-bedrock is explicitly refused: the shared llm block is a single url+auth_token endpoint, while Bedrock derives its host from aws_region and authenticates via the AWS credential chain, so the llm.* fields have nowhere to hold region/profile. The code rejects the value at set-time instead of silently ignoring it at resolve-time.

Source

Thrown at cmd/opencodereview/config_cmd.go:539

		cfg.Llm.AuthHeader = normalized
	case "llm.extra_headers", "llm.ExtraHeaders":
		parsed, err := llm.ParseExtraHeaders(value)
		if err != nil {
			return err
		}
		cfg.Llm.ExtraHeaders = parsed
	case "llm.model", "llm.Model":
		cfg.Llm.Model = value
	case "llm.protocol", "llm.Protocol":
		normalized := llm.NormalizeProtocol(value)
		if err := llm.ValidateProtocol(normalized); err != nil {
			return err
		}
		// The llm block is a single url + token endpoint. Bedrock needs neither
		// and has nowhere here to put a region or a profile, so it is refused at
		// the point of setting rather than accepted and ignored at resolve time.
		if normalized == llm.ProtocolAnthropicBedrock {
			return fmt.Errorf("llm.protocol cannot be %q: bedrock derives its host from aws_region and signs with the AWS credential chain, so it has no use for llm.url or llm.auth_token; run `ocr config set provider bedrock` instead", normalized)
		}
		cfg.Llm.Protocol = normalized
		// Mirror use_anthropic so older binaries that predate llm.protocol
		// still pick the right protocol family: anthropic -> true, the OpenAI
		// family (including openai-responses) -> false.
		if normalized == llm.ProtocolAnthropic {
			t := true
			cfg.Llm.UseAnthropic = &t
		} else {
			f := false
			cfg.Llm.UseAnthropic = &f
		}
	case "llm.use_anthropic", "llm.UseAnthropic":
		b, err := strconv.ParseBool(value)
		if err != nil {
			return fmt.Errorf("invalid boolean for llm.use_anthropic: %w", err)
		}
		cfg.Llm.UseAnthropic = &b

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Run `ocr config set provider bedrock` instead of setting llm.protocol
  2. Set the region with `ocr config set providers.bedrock.aws_region <region>` (and optionally aws_profile)
  3. If you need a custom Bedrock-compatible endpoint, configure it as a provider entry, not the llm block
  4. Check `ocr config get` to confirm the current provider and protocol

Example fix

// before
ocr config set llm.protocol anthropic-bedrock
// after
ocr config set provider bedrock
ocr config set providers.bedrock.aws_region us-east-1
Defensive patterns

Strategy: validation

Validate before calling

if strings.EqualFold(strings.TrimSpace(protocol), "anthropic-bedrock") {
    // route through provider config instead of llm.protocol
    return runConfigSet("provider", "bedrock")
}
return runConfigSet("llm.protocol", protocol)

Try / catch

if err := runConfigSet("llm.protocol", p); err != nil {
    if strings.Contains(err.Error(), "cannot be") && strings.Contains(err.Error(), "bedrock") {
        return runConfigSet("provider", "bedrock") // auto-fallback
    }
    return err
}

Prevention

When it happens

Trigger: `ocr config set llm.protocol anthropic-bedrock` (in any casing that normalizes to bedrock) while the key is accepted in the provider-level `protocol` field.

Common situations: Migrating a generic llm.* endpoint config to Bedrock; following outdated docs that put bedrock under llm.protocol; scripting config generation that mirrors provider fields into the llm block.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/dc63bea415b44e95. Report an issue: GitHub.