chenhg5/cc-connect · error
no OPENAI_API_KEY found
Error message
no OPENAI_API_KEY found
What it means
convertCodexProvider builds a Codex provider entry from cc-switch data. After applying the config TOML (base_url, model), it requires an API key; if p.APIKey is still empty it refuses to return a usable provider and returns this error. It exists so a Codex provider without credentials is never silently used.
Source
Thrown at cmd/cc-connect/provider.go:417
}
return p, nil
}
func convertCodexProvider(p config.ProviderConfig, sc map[string]any) (config.ProviderConfig, error) {
// API key from auth.OPENAI_API_KEY
if auth, ok := sc["auth"].(map[string]any); ok {
if key, ok := auth["OPENAI_API_KEY"].(string); ok && key != "" {
p.APIKey = key
}
}
// base_url and model from config TOML string
if cfgStr, ok := sc["config"].(string); ok && cfgStr != "" {
p.BaseURL, p.Model = parseCodexConfigTOML(cfgStr)
}
if p.APIKey == "" {
return p, fmt.Errorf("no OPENAI_API_KEY found")
}
return p, nil
}
// parseCodexConfigTOML extracts base_url and model from a Codex config.toml string.
// It handles both flat `base_url = "..."` and upstream-style `[model_providers.X]` sections.
func parseCodexConfigTOML(cfgStr string) (baseURL, model string) {
for _, line := range strings.Split(cfgStr, "\n") {
line = strings.TrimSpace(line)
if k, v, ok := parseTOMLKV(line); ok {
switch k {
case "base_url":
if baseURL == "" {
baseURL = v
}
case "model":
if model == "" {
model = vView on GitHub (pinned to 4000b2338a)
Solutions
- Open the provider entry in cc-switch (or its settings JSON) and set the OpenAI API key field.
- Export OPENAI_API_KEY in the environment cc-connect runs under if the provider is meant to inherit it.
- Re-import the provider from a complete config.toml that includes the key, then retry.
Example fix
// before (provider settings in cc-switch)
{ "name": "my-provider", "config": "model_provider = ..." }
// after
{ "name": "my-provider", "apiKey": "sk-...", "config": "model_provider = ..." } Defensive patterns
Strategy: validation
Validate before calling
if apiKey, _ := prov["apiKey"].(string); strings.TrimSpace(apiKey) == "" {
return fmt.Errorf("provider %q has no OPENAI_API_KEY; set it in cc-switch before use", prov["name"])
} Type guard
apiKey, ok := sc["apiKey"].(string); if !ok || strings.TrimSpace(apiKey) == "" { /* treat as unconfigured */ } Try / catch
p, err := convertCCSwitchProvider(rec)
if err != nil {
if strings.Contains(err.Error(), "no OPENAI_API_KEY") {
slog.Warn("skipping provider without API key", "provider", rec.Name)
return
}
return err
} Prevention
- Always fill the API key when creating a provider entry in cc-switch.
- Validate provider records at import time, not at use time.
- Keep keys in environment or secret store rather than omitting them.
When it happens
Trigger: Calling convertCCSwitchProvider/convertCodexProvider with a provider record whose api key field (OPENAI_API_KEY / apiKey in the cc-switch DB or settings JSON) is missing or empty.
Common situations: User imported a provider into cc-switch but never filled in OPENAI_API_KEY; key stored under an unexpected JSON key so parsing misses it; provider uses only env-var auth (e.g. ChatGPT login) with no explicit key.
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
- parse existing Agy hooks %s: %w
- marshal Agy hooks overlay: %w
- read %s: %w
- parse auth.json: %w
- auth.json missing tokens.access_token
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/202c8ab7059cf038.
Report an issue: GitHub.