{"record":{"id":"2894141aaef31c9b","repo":"alibaba/open-code-review","slug":"resolve-ocr-config-file-provider-q-is-not-config","errorCode":null,"errorMessage":"resolve OCR config file: provider %q is not configured in %s section because the config file does not exist","messagePattern":"resolve OCR config file: provider %q is not configured in (.+?) section because the config file does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/resolver.go","lineNumber":121,"sourceCode":"\t// unparseable OCR_LLM_EXTRA_HEADERS abort resolution *after* api_key_cmd\n\t// already prompted 1Password/pinentry/Touch ID for a credential that then\n\t// gets discarded.\n\tenv, err := parseEnvOverrides()\n\tif err != nil {\n\t\treturn ResolvedEndpoint{}, err\n\t}\n\n\tif opts.Provider != \"\" {\n\t\tep, ok, err := tryOCRConfig(configPath, opts)\n\t\tif err != nil {\n\t\t\treturn ResolvedEndpoint{}, fmt.Errorf(\"resolve OCR config file: %w\", err)\n\t\t}\n\t\tif !ok {\n\t\t\tsection := \"custom_providers\"\n\t\t\tif _, isPreset := LookupProvider(opts.Provider); isPreset {\n\t\t\t\tsection = \"providers\"\n\t\t\t}\n\t\t\treturn ResolvedEndpoint{}, fmt.Errorf(\"resolve OCR config file: provider %q is not configured in %s section because the config file does not exist\", opts.Provider, section)\n\t\t}\n\t\treturn finalizeResolvedEndpoint(\"OCR config file\", ep, env), nil\n\t}\n\n\tstrategies := []struct {\n\t\tname string\n\t\tfn   func() (ResolvedEndpoint, bool, error)\n\t}{\n\t\t{\"OCR config file\", func() (ResolvedEndpoint, bool, error) { return tryOCRConfig(configPath, opts) }},\n\t\t{\"OCR environment\", func() (ResolvedEndpoint, bool, error) { return tryOCREnv(opts.Model) }},\n\t\t{\"Claude Code environment\", func() (ResolvedEndpoint, bool, error) { return tryCCEnv(opts.Model) }},\n\t\t{\"Shell rc file\", func() (ResolvedEndpoint, bool, error) { return tryShellRC(opts.Model) }},\n\t}\n\n\tfor _, strategy := range strategies {\n\t\tep, ok, err := strategy.fn()\n\t\tif err != nil {\n\t\t\treturn ResolvedEndpoint{}, fmt.Errorf(\"resolve %s: %w\", strategy.name, err)","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/resolver.go#L103-L139","documentation":"When an explicit Provider is requested, the resolver requires an entry in the OCR config file; there is no env fallback for that path. If tryOCRConfig reports ok=false — which for this path effectively means the config file does not exist or the provider has no usable entry — the resolver fails with a message naming the expected section: \"providers\" for built-in presets (LookupProvider hit) or \"custom_providers\" for anything else.","triggerScenarios":"Calling ResolveEndpointWithOptions with ResolveOptions.Provider set while ~/.opencodereview/config.json does not exist, or lacks the provider in the section matching its preset status (built-in preset -> \"providers\", custom -> \"custom_providers\").","commonSituations":"Passing --provider mycustomvendor on a fresh machine with no config file; putting a custom provider under \"providers\" instead of \"custom_providers\" (or vice versa); typo in the provider key so LookupProvider misses and it is looked up in custom_providers where it also is absent.","solutions":["Create ~/.opencodereview/config.json and add the provider under the section named in the error","If it is a built-in preset, put it under \"providers\"; if custom, under \"custom_providers\"","Check the provider name spelling matches the key in the config file","Drop the explicit provider so the resolver falls back to env/shell-rc strategies"],"exampleFix":"// before (no config file, custom provider \"acme\")\nocr review --provider acme\n// after: ~/.opencodereview/config.json\n{\"custom_providers\": {\"acme\": {\"url\": \"https://api.acme.com\", \"api_key\": \"...\", \"model\": \"...\", \"protocol\": \"openai\"}}}","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(cfgPath); os.IsNotExist(err) {\n    return fmt.Errorf(\"config %s missing; create it before using --provider\", cfgPath)\n}","typeGuard":null,"tryCatchPattern":"_, err := llm.ResolveEndpointWithOptions(path, llm.ResolveOptions{Provider: name})\nif err != nil && strings.Contains(err.Error(), \"does not exist\") {\n    return fmt.Errorf(\"add provider %q to the config file first\", name)\n}","preventionTips":["Confirm the config file exists before passing an explicit provider","Put built-in presets under \"providers\" and custom vendors under \"custom_providers\"","Match provider keys exactly (case-sensitive) to the section entry"],"tags":["config","missing-config","resolution"],"backgroundTag":"missing-config-file","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}