{"record":{"id":"55c0d801285ea507","repo":"alibaba/open-code-review","slug":"resolve-ocr-config-file-w","errorCode":null,"errorMessage":"resolve OCR config file: %w","messagePattern":"resolve OCR config file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/resolver.go","lineNumber":114,"sourceCode":"func ResolveEndpointWithOptions(configPath string, opts ResolveOptions) (ResolvedEndpoint, error) {\n\topts.Provider = strings.TrimSpace(opts.Provider)\n\topts.Model = strings.TrimSpace(opts.Model)\n\n\t// The global env overrides are parsed before any strategy runs, even though\n\t// they are applied to the endpoint afterwards. Parsing them inside\n\t// finalizeResolvedEndpoint would let a typo'd OCR_LLM_TIMEOUT (\"30s\") or an\n\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) }},","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/resolver.go#L96-L132","documentation":"When ResolveEndpointWithOptions is called with an explicit Provider, it tries tryOCRConfig to load that provider's entry from the OCR config file. Any error reading/parsing that file (missing required fields, unreadable file, malformed JSON) is wrapped as \"resolve OCR config file: %w\" and aborts resolution. It signals the config file exists but could not be used, distinct from the not-found error [272].","triggerScenarios":"Calling ResolveEndpointWithOptions/ResolveEndpoint/ResolveEndpointWithModelOverride with ResolveOptions.Provider set, while tryOCRConfig fails to read or parse ~/.opencodereview/config.json (or the given configPath) — e.g. invalid JSON, a bad schema field, or a permission error.","commonSituations":"Hand-edited config.json with a JSON syntax error; a config file written by a newer version with unknown/invalid fields; a path passed explicitly that points to a directory or unreadable file.","solutions":["Read the wrapped cause (%w) to see the underlying read/parse failure and fix the config file","Validate ~/.opencodereview/config.json is well-formed JSON (e.g. with jq .)","If you only wanted a preset provider with env-based credentials, unset the explicit provider so env strategies are tried instead"],"exampleFix":"// before\n{\"providers\": {\"deepseek\": {\"api_key\": }} }\n// after\n{\"providers\": {\"deepseek\": {\"api_key\": \"sk-...\"}}}","handlingStrategy":"validation","validationCode":"f, err := os.Open(configPath)\nif err != nil { return err }\ndefer f.Close()\nvar cfg map[string]any\nif err := json.NewDecoder(f).Decode(&cfg); err != nil {\n    return fmt.Errorf(\"config %s is not valid JSON: %w\", configPath, err)\n}","typeGuard":null,"tryCatchPattern":"ep, err := llm.ResolveEndpointWithOptions(path, opts)\nvar perr *json.SyntaxError\nif errors.As(err, &perr) {\n    // config file parse failure wrapped as \"resolve OCR config file: ...\"\n    log.Fatalf(\"fix config %s: %v\", path, err)\n}","preventionTips":["Validate config.json with jq or a schema check after every manual edit","Back up config.json before ocr version upgrades","Use LF line endings and UTF-8 to avoid parse surprises"],"tags":["config","file-io","resolution"],"backgroundTag":"config-file-parse-error","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}