alibaba/open-code-review · error

OCR config file: %w

Error message

OCR config file: %w

What it means

In the legacy [llm] config block, llm.protocol (after normalization) must pass ValidateProtocol. This error reports an unrecognized/invalid protocol value in the legacy config, prefixed with "OCR config file:" to point at the file.

Source

Thrown at internal/llm/resolver.go:631

	tokenCmd := cfg.Llm.AuthTokenCmd
	if strings.TrimSpace(tokenCmd) == "" {
		tokenCmd = ""
	}
	if cfg.Llm.URL == "" || model == "" || (token == "" && tokenCmd == "") {
		return ResolvedEndpoint{}, false, nil
	}
	// Static auth_token always wins; warn if a command is also set. The command
	// itself runs only just before returning, after the validation below.
	if token != "" && tokenCmd != "" {
		fmt.Fprintln(os.Stderr, "[ocr] WARNING: llm config has both auth_token and auth_token_cmd set; using the static auth_token")
	}

	// llm.protocol (normalized) wins over use_anthropic when set.
	protocol := ""
	if raw := strings.TrimSpace(cfg.Llm.Protocol); raw != "" {
		protocol = NormalizeProtocol(raw)
		if err := ValidateProtocol(protocol); err != nil {
			return ResolvedEndpoint{}, false, fmt.Errorf("OCR config file: %w", err)
		}
		if protocol == ProtocolAnthropicBedrock {
			return ResolvedEndpoint{}, false, fmt.Errorf("OCR config file: %w", errBedrockNotConfigurable("llm.protocol"))
		}
	}
	if protocol == "" {
		useAnthropic := true // default true
		if cfg.Llm.UseAnthropic != nil {
			useAnthropic = *cfg.Llm.UseAnthropic
		}
		if useAnthropic {
			protocol = ProtocolAnthropic
		} else {
			protocol = ProtocolOpenAIChatCompletions
		}
	}

	var authHeader string

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Set llm.protocol to a supported value (e.g. "anthropic", "openai", "openai-chat-completions")
  2. Or delete the llm.protocol line and rely on use_anthropic (true/false) to pick the protocol
  3. Run the normalization mentally: the value is case/spacing normalized before validation, so fix spelling rather than casing

Example fix

// before
[llm]
protocol = "gpt4"

// after
[llm]
protocol = "openai-chat-completions"
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-validate a legacy llm.protocol value
func validLegacyProtocol(raw string) error {
	switch strings.ToLower(strings.TrimSpace(raw)) {
	case "", "anthropic", "openai", "openai-chat-completions":
		return nil
	default:
		return fmt.Errorf("unsupported llm.protocol %q", raw)
	}
}

Type guard

func isKnownProtocol(raw string) bool {
	switch strings.ToLower(strings.TrimSpace(raw)) {
	case "anthropic", "openai", "openai-chat-completions":
		return true
	}
	return false
}

Try / catch

ep, ok, err := resolver.TryResolve(ctx, cfg)
if err != nil && strings.HasPrefix(err.Error(), "OCR config file:") {
	fmt.Fprintf(os.Stderr, "fix [llm] block in ocr config: %v\n", err)
	os.Exit(2)
}

Prevention

When it happens

Trigger: tryLegacyLlmConfig runs when a complete legacy [llm] block exists (url + model + token/token_cmd) and cfg.Llm.Protocol is non-empty but does not normalize to a known protocol.

Common situations: Migrating old configs with protocol values like "openai-chat" or "gpt" that no longer match the accepted set; typos ("antropic"); case/format drift from older versions.

Related errors


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