{"record":{"id":"2a0f411c79e31bee","repo":"alibaba/open-code-review","slug":"provider-q-is-set-but-not-configured-in-s-sectio","errorCode":null,"errorMessage":"provider %q is set but not configured in %s section","messagePattern":"provider %q is set but not configured in (.+?) section","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/resolver.go","lineNumber":386,"sourceCode":"}\n\n// tryProviderConfig resolves an endpoint from the provider-based configuration.\nfunc tryProviderConfig(cfg configFile, modelOverride string) (ResolvedEndpoint, bool, error) {\n\tpreset, isPreset := LookupProvider(cfg.Provider)\n\n\tvar entry providerEntryConfig\n\tvar ok bool\n\tif isPreset {\n\t\tentry, ok = cfg.Providers[cfg.Provider]\n\t} else {\n\t\tentry, ok = cfg.CustomProviders[cfg.Provider]\n\t}\n\tif !ok {\n\t\tsection := \"providers\"\n\t\tif !isPreset {\n\t\t\tsection = \"custom_providers\"\n\t\t}\n\t\treturn ResolvedEndpoint{}, false, fmt.Errorf(\"provider %q is set but not configured in %s section\", cfg.Provider, section)\n\t}\n\n\t// Pick the credential source here, but run api_key_cmd only just before\n\t// returning (see below): a config typo must not trigger a secret-manager\n\t// prompt before the cheap validation below has had a chance to fail.\n\t// A whitespace-only api_key is a typo, not a credential: treat it as unset so\n\t// it cannot silently shadow a working api_key_cmd (which otherwise resolves to\n\t// a 401 with the command never running). A key with real content is used\n\t// verbatim -- unlike command stdout, which has a mechanical trailing newline\n\t// to strip, a static value has no artifact that trimming must undo.\n\tapiKey := entry.APIKey\n\tif strings.TrimSpace(apiKey) == \"\" {\n\t\tapiKey = \"\"\n\t}\n\t// Same rule for the command: `sh -c \"   \"` exits 0 with no output, so a\n\t// whitespace-only api_key_cmd would suppress the env fallback and then fail\n\t// with \"produced empty output\". Treating it as unset keeps the typo from\n\t// being more disruptive than the equivalent typo in api_key.","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/resolver.go#L368-L404","documentation":"tryProviderConfig fails with this error when the top-level \"provider\" key names a provider that has no matching entry in the config file. Preset providers must appear under \"providers\", custom providers under \"custom_providers\"; the error names the correct section for the chosen provider.","triggerScenarios":"config.json (or --provider override) sets \"provider\": \"X\", but cfg.Providers has no key \"X\" when X is a known preset, or cfg.CustomProviders has no key \"X\" when X is not a preset.","commonSituations":"Typo in the provider name; putting a preset name under custom_providers or a custom name under providers; deleting the entry while leaving \"provider\" set; passing --provider with a name never configured.","solutions":["Add a matching entry under the section named in the error (\"providers\" for presets, \"custom_providers\" for custom ones) keyed by the exact provider name","Fix the spelling of \"provider\" so it matches an existing entry key","Remove the \"provider\" key to fall back to the legacy llm block configuration","If using --provider, pass a name that exists in the config"],"exampleFix":"// before\n{ \"provider\": \"deepseek\" }\n\n// after\n{\n  \"provider\": \"deepseek\",\n  \"providers\": { \"deepseek\": { \"model\": \"deepseek-chat\" } }\n}","handlingStrategy":"validation","validationCode":"var cfg struct {\n    Provider        string            `json:\"provider\"`\n    Providers       map[string]any    `json:\"providers\"`\n    CustomProviders map[string]any    `json:\"custom_providers\"`\n}\njson.Unmarshal(data, &cfg)\nif cfg.Provider != \"\" {\n    if _, ok := cfg.Providers[cfg.Provider]; !ok {\n        if _, ok := cfg.CustomProviders[cfg.Provider]; !ok {\n            return fmt.Errorf(\"provider %q has no entry in providers or custom_providers\", cfg.Provider)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always add the provider entry in the same edit that sets \"provider\"","Copy the provider name (paste, don't retype) between \"provider\" and the section key","Remember presets live under \"providers\", custom ones under \"custom_providers\"","Grep the config for \"provider\" before removing entries"],"tags":["configuration","provider","missing-config"],"backgroundTag":"provider-not-configured","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}