{"record":{"id":"b46282d4ad7476bc","repo":"alibaba/open-code-review","slug":"ocr-config-file-w","errorCode":null,"errorMessage":"OCR config file: %w","messagePattern":"OCR config file: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/resolver.go","lineNumber":631,"sourceCode":"\ttokenCmd := cfg.Llm.AuthTokenCmd\n\tif strings.TrimSpace(tokenCmd) == \"\" {\n\t\ttokenCmd = \"\"\n\t}\n\tif cfg.Llm.URL == \"\" || model == \"\" || (token == \"\" && tokenCmd == \"\") {\n\t\treturn ResolvedEndpoint{}, false, nil\n\t}\n\t// Static auth_token always wins; warn if a command is also set. The command\n\t// itself runs only just before returning, after the validation below.\n\tif token != \"\" && tokenCmd != \"\" {\n\t\tfmt.Fprintln(os.Stderr, \"[ocr] WARNING: llm config has both auth_token and auth_token_cmd set; using the static auth_token\")\n\t}\n\n\t// llm.protocol (normalized) wins over use_anthropic when set.\n\tprotocol := \"\"\n\tif raw := strings.TrimSpace(cfg.Llm.Protocol); raw != \"\" {\n\t\tprotocol = NormalizeProtocol(raw)\n\t\tif err := ValidateProtocol(protocol); err != nil {\n\t\t\treturn ResolvedEndpoint{}, false, fmt.Errorf(\"OCR config file: %w\", err)\n\t\t}\n\t\tif protocol == ProtocolAnthropicBedrock {\n\t\t\treturn ResolvedEndpoint{}, false, fmt.Errorf(\"OCR config file: %w\", errBedrockNotConfigurable(\"llm.protocol\"))\n\t\t}\n\t}\n\tif protocol == \"\" {\n\t\tuseAnthropic := true // default true\n\t\tif cfg.Llm.UseAnthropic != nil {\n\t\t\tuseAnthropic = *cfg.Llm.UseAnthropic\n\t\t}\n\t\tif useAnthropic {\n\t\t\tprotocol = ProtocolAnthropic\n\t\t} else {\n\t\t\tprotocol = ProtocolOpenAIChatCompletions\n\t\t}\n\t}\n\n\tvar authHeader string","sourceCodeStart":613,"sourceCodeEnd":649,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/resolver.go#L613-L649","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set llm.protocol to a supported value (e.g. \"anthropic\", \"openai\", \"openai-chat-completions\")","Or delete the llm.protocol line and rely on use_anthropic (true/false) to pick the protocol","Run the normalization mentally: the value is case/spacing normalized before validation, so fix spelling rather than casing"],"exampleFix":"// before\n[llm]\nprotocol = \"gpt4\"\n\n// after\n[llm]\nprotocol = \"openai-chat-completions\"","handlingStrategy":"validation","validationCode":"// Go: pre-validate a legacy llm.protocol value\nfunc validLegacyProtocol(raw string) error {\n\tswitch strings.ToLower(strings.TrimSpace(raw)) {\n\tcase \"\", \"anthropic\", \"openai\", \"openai-chat-completions\":\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported llm.protocol %q\", raw)\n\t}\n}","typeGuard":"func isKnownProtocol(raw string) bool {\n\tswitch strings.ToLower(strings.TrimSpace(raw)) {\n\tcase \"anthropic\", \"openai\", \"openai-chat-completions\":\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"ep, ok, err := resolver.TryResolve(ctx, cfg)\nif err != nil && strings.HasPrefix(err.Error(), \"OCR config file:\") {\n\tfmt.Fprintf(os.Stderr, \"fix [llm] block in ocr config: %v\\n\", err)\n\tos.Exit(2)\n}","preventionTips":["Use only documented protocol values in llm.protocol","Prefer use_anthropic = true/false over llm.protocol when only choosing between the two defaults","Migrate legacy [llm] blocks to [providers] entries where protocol validation is consistent"],"tags":["config","legacy","validation"],"backgroundTag":"invalid-protocol-value","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}