alibaba/open-code-review · error

API key is required for provider %s (configure it or set pro

Error message

API key is required for provider %s (configure it or set providers.%s.api_key_cmd)

What it means

The default branch of checkAPIKeyRequirement handles providers that are not ambient-auth presets and have no env-var preset: no API key source could be determined, so config application is refused with guidance to configure the key directly or via providers.<name>.api_key_cmd.

Source

Thrown at cmd/opencodereview/provider_cmd.go:256

// here and then fail resolution with "no api_key or api_key_cmd configured".
//
// An ambient-auth provider has no credential to save at all: demanding one would
// make it impossible to configure, since the credentials live in the AWS chain
// rather than the config file.
func checkAPIKeyRequirement(providerName, apiKey, apiKeyCmd string, preset llm.Provider, isPreset bool) error {
	if apiKey != "" || strings.TrimSpace(apiKeyCmd) != "" {
		return nil
	}
	switch {
	case isPreset && preset.AmbientAuth:
		return nil
	case isPreset && preset.EnvVar != "":
		if os.Getenv(preset.EnvVar) == "" {
			return fmt.Errorf("API key is required for provider %s (configure it, set providers.%s.api_key_cmd, or set $%s)", providerName, providerName, preset.EnvVar)
		}
		return nil
	default:
		return fmt.Errorf("API key is required for provider %s (configure it or set providers.%s.api_key_cmd)", providerName, providerName)
	}
}

func applyOfficialProviderConfig(configPath string, cfg *Config, result providerTUIResult) error {
	if result.provider == "" {
		return fmt.Errorf("provider and model are required")
	}
	model := result.resolvedModel()
	if model == "" {
		return fmt.Errorf("provider and model are required")
	}

	preset, isPreset := llm.LookupProvider(result.provider)

	if err := checkAPIKeyRequirement(result.provider, result.apiKey, cfg.Providers[result.provider].APIKeyCmd, preset, isPreset); err != nil {
		return err
	}

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Provide the API key in the wizard (result.apiKey) when running 'ocr config provider'
  2. Set providers.<name>.api_key_cmd in the config file to a command that prints the key
  3. Check the provider name spelling so it matches a preset in llm.LookupProvider (presets may support env vars)

Example fix

// before (config.toml)
[providers.my-gateway]
# no api_key, no api_key_cmd
// after
[providers.my-gateway]
api_key_cmd = ["op", "read", "op://vault/gateway-key"]
Defensive patterns

Strategy: validation

Validate before calling

if result.apiKey == "" && cfg.Providers[name].APIKeyCmd == "" {
    // supply key in wizard or set api_key_cmd before applying
}

Try / catch

if err := applyOfficialProviderConfig(path, cfg, result); err != nil && strings.Contains(err.Error(), "API key is required") {
    // prompt for the key or configure api_key_cmd and retry once
}

Prevention

When it happens

Trigger: checkAPIKeyRequirement is called for a provider that either is not a known preset, or is a preset with AmbientAuth=false and empty EnvVar, while result.apiKey is empty and cfg.Providers[name].APIKeyCmd is also empty.

Common situations: Self-hosted or gateway providers not in the preset registry; a misspelled provider name so LookupProvider fails and isPreset is false; existing config entry lacking api_key_cmd after upgrading; wizard completed with the key field left blank.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/d381f9d9090e95e1. Report an issue: GitHub.