alibaba/open-code-review · error
provider %q is set but not configured in %s section
Error message
provider %q is set but not configured in %s section
What it means
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.
Source
Thrown at internal/llm/resolver.go:386
}
// tryProviderConfig resolves an endpoint from the provider-based configuration.
func tryProviderConfig(cfg configFile, modelOverride string) (ResolvedEndpoint, bool, error) {
preset, isPreset := LookupProvider(cfg.Provider)
var entry providerEntryConfig
var ok bool
if isPreset {
entry, ok = cfg.Providers[cfg.Provider]
} else {
entry, ok = cfg.CustomProviders[cfg.Provider]
}
if !ok {
section := "providers"
if !isPreset {
section = "custom_providers"
}
return ResolvedEndpoint{}, false, fmt.Errorf("provider %q is set but not configured in %s section", cfg.Provider, section)
}
// Pick the credential source here, but run api_key_cmd only just before
// returning (see below): a config typo must not trigger a secret-manager
// prompt before the cheap validation below has had a chance to fail.
// A whitespace-only api_key is a typo, not a credential: treat it as unset so
// it cannot silently shadow a working api_key_cmd (which otherwise resolves to
// a 401 with the command never running). A key with real content is used
// verbatim -- unlike command stdout, which has a mechanical trailing newline
// to strip, a static value has no artifact that trimming must undo.
apiKey := entry.APIKey
if strings.TrimSpace(apiKey) == "" {
apiKey = ""
}
// Same rule for the command: `sh -c " "` exits 0 with no output, so a
// whitespace-only api_key_cmd would suppress the env fallback and then fail
// with "produced empty output". Treating it as unset keeps the typo from
// being more disruptive than the equivalent typo in api_key.View on GitHub (pinned to 5cf97d0d15)
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
Example fix
// before
{ "provider": "deepseek" }
// after
{
"provider": "deepseek",
"providers": { "deepseek": { "model": "deepseek-chat" } }
} Defensive patterns
Strategy: validation
Validate before calling
var cfg struct {
Provider string `json:"provider"`
Providers map[string]any `json:"providers"`
CustomProviders map[string]any `json:"custom_providers"`
}
json.Unmarshal(data, &cfg)
if cfg.Provider != "" {
if _, ok := cfg.Providers[cfg.Provider]; !ok {
if _, ok := cfg.CustomProviders[cfg.Provider]; !ok {
return fmt.Errorf("provider %q has no entry in providers or custom_providers", cfg.Provider)
}
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- provider %q: %w
- custom provider %q not found
- provider name is required
- model is required
- API key is required for provider %s (configure it, set provi
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/2a0f411c79e31bee.
Report an issue: GitHub.