alibaba/open-code-review · error
unsupported protocol %q; supported protocols are %q, %q, %q,
Error message
unsupported protocol %q; supported protocols are %q, %q, %q, %q
What it means
ValidateProtocol accepts only the four canonical protocol names built into open-code-review: "anthropic", "openai", "openai-responses", and "anthropic-bedrock". It is the whitelist gate used by config parsing, provider field application, and the LLM client factory. Any other (case-normalized) value fails with this error listing every accepted name.
Source
Thrown at internal/llm/protocol.go:70
case ProtocolOpenAIChatCompletions:
return ProtocolOpenAIChatCompletions
case ProtocolOpenAIResponses:
return ProtocolOpenAIResponses
case ProtocolAnthropicBedrock:
return ProtocolAnthropicBedrock
default:
return normalized
}
}
// ValidateProtocol accepts the four canonical protocol names and rejects
// everything else.
func ValidateProtocol(p string) error {
switch p {
case ProtocolAnthropic, ProtocolOpenAIChatCompletions, ProtocolOpenAIResponses, ProtocolAnthropicBedrock:
return nil
default:
return fmt.Errorf("unsupported protocol %q; supported protocols are %q, %q, %q, %q", p, ProtocolAnthropic, ProtocolOpenAIChatCompletions, ProtocolOpenAIResponses, ProtocolAnthropicBedrock)
}
}
View on GitHub (pinned to 5cf97d0d15)
Solutions
- Use one of the exact names: "anthropic", "openai", "openai-responses", or "anthropic-bedrock"
- Call llm.NormalizeProtocol(raw) first, then ValidateProtocol on the result, to see the canonical form in the error
- If you need Bedrock, use "anthropic-bedrock" with AWS credentials in the environment rather than a custom protocol string
Example fix
// before protocol: "openai-chat" // after protocol: "openai"
Defensive patterns
Strategy: validation
Validate before calling
p := llm.NormalizeProtocol(raw)
if err := llm.ValidateProtocol(p); err != nil {
return fmt.Errorf("config protocol %q invalid: %w", raw, err)
} Type guard
func isKnownProtocol(p string) bool {
switch llm.NormalizeProtocol(p) {
case llm.ProtocolAnthropic, llm.ProtocolOpenAIChatCompletions,
llm.ProtocolOpenAIResponses, llm.ProtocolAnthropicBedrock:
return true
}
return false
} Prevention
- Always run NormalizeProtocol before ValidateProtocol so case/whitespace typos are forgiven
- Keep protocol strings as the exported llm.Protocol* constants in generated configs
- Validate config.json once at startup, not per request
When it happens
Trigger: Setting a protocol value in a provider/custom_providers config section, via applyProviderField, or via OCR_LLM_PROTOCOL that is not one of the four canonical names — e.g. "OpenAI" (NormalizeProtocol lowercases, so case is fine, but "openai-chat" or "gpt" are not), a misspelling like "anthropic-bedrock " is trimmed but "bedrock" alone is rejected.
Common situations: Typing a protocol alias by hand in ~/.opencodereview/config.json; copying a vendor doc name like "chat-completions" or "azure-openai"; using an old custom value from before "openai-responses"/"anthropic-bedrock" were introduced.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- invalid max_tokens %q: must be a positive integer
- unknown config key: %s Supported keys: %s Provider fields: a
- invalid URL for %s: %w
- invalid model list for %s: %w
- invalid retry codes for %s: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/d16d260733f657ef.
Report an issue: GitHub.