chenhg5/cc-connect · error

no env in settings_config

Error message

no env in settings_config

What it means

convertClaudeProvider expects the parsed settings_config JSON to contain an `env` object holding Claude's environment (ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, etc.). When settings_config parses as JSON but has no usable `env` key (or it is not an object), this error is returned. Without env there is nothing to extract an API key or base URL from.

Solutions

  1. Edit the row so settings_config contains an `env` object with ANTHROPIC_AUTH_TOKEN/ANTHROPIC_BASE_URL.
  2. Recreate the provider in cc-switch so it writes the correct structure.
  3. Check the env value is an object, not a string.
  4. If env lives under a different key in your data, migrate it into `env` before importing.

Example fix

// before (settings_config)
{"model": "claude-3"}
// error: no env in settings_config
// after
{"env": {"ANTHROPIC_AUTH_TOKEN": "sk-...", "ANTHROPIC_BASE_URL": "https://api.example.com"}}
Defensive patterns

Strategy: validation

Validate before calling

func claudeSettingsUsable(settingsJSON string) bool {
    var sc map[string]any
    if json.Unmarshal([]byte(settingsJSON), &sc) != nil { return false }
    env, ok := sc["env"].(map[string]any)
    return ok && len(env) > 0
}

Type guard

env, ok := sc["env"].(map[string]any)
if !ok || env == nil {
    return p, fmt.Errorf("no env in settings_config")
}

Try / catch

p, err := convertCCSwitchProvider(row)
if err != nil && strings.Contains(err.Error(), "no env in settings_config") {
    return fmt.Errorf("provider %q has no env block; re-create it in cc-switch", row.Name)
}

Prevention

When it happens

Trigger: A cc-switch claude row's settings_config is a JSON object lacking `env` — e.g. {"model":"..."} or {"env": "string"} (wrong type, so the assertion to map[string]any fails and env is nil).

Common situations: Manually crafted DB rows; a different tool writing claude-like settings without env; cc-switch version storing env under another key like "environment".

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/09ef435f951d18be. Report an issue: GitHub.

Appendix: source

Thrown at cmd/cc-connect/provider.go:370

	p := config.ProviderConfig{
		Name: strings.ToLower(strings.ReplaceAll(strings.TrimSpace(row.Name), " ", "-")),
	}

	switch row.AppType {
	case "claude":
		return convertClaudeProvider(p, sc)
	case "codex":
		return convertCodexProvider(p, sc)
	default:
		return config.ProviderConfig{}, fmt.Errorf("unsupported app_type %q (only claude and codex are supported)", row.AppType)
	}
}

func convertClaudeProvider(p config.ProviderConfig, sc map[string]any) (config.ProviderConfig, error) {
	env, _ := sc["env"].(map[string]any)
	if env == nil {
		return p, fmt.Errorf("no env in settings_config")
	}

	if key, ok := env["ANTHROPIC_AUTH_TOKEN"].(string); ok && key != "" {
		p.APIKey = key
	}
	if url, ok := env["ANTHROPIC_BASE_URL"].(string); ok && url != "" {
		p.BaseURL = url
	}
	if model, ok := env["ANTHROPIC_MODEL"].(string); ok && model != "" {
		p.Model = model
	}

	// Carry over any extra env vars (e.g. ANTHROPIC_DEFAULT_HAIKU_MODEL)
	extra := make(map[string]string)
	known := map[string]bool{"ANTHROPIC_AUTH_TOKEN": true, "ANTHROPIC_BASE_URL": true, "ANTHROPIC_MODEL": true}
	for k, v := range env {
		if !known[k] {
			if s, ok := v.(string); ok && s != "" {

View on GitHub (pinned to 4000b2338a)