chenhg5/cc-connect · error

global provider %q already exists

Error message

global provider %q already exists

What it means

The global-provider add path (loadLocked + append to cfg.Providers) rejects a provider whose name already exists in the top-level [[providers]] list, returning 'global provider %q already exists'. Global provider names are unique keys across the whole config.

Source

Thrown at config/config.go:1473

	defer configMu.Unlock()
	cfg, err := loadLocked()
	if err != nil {
		return nil, err
	}
	return cfg.Providers, nil
}

// AddGlobalProvider appends a provider to the top-level [[providers]] and saves.
func AddGlobalProvider(provider ProviderConfig) error {
	configMu.Lock()
	defer configMu.Unlock()
	cfg, err := loadLocked()
	if err != nil {
		return err
	}
	for _, existing := range cfg.Providers {
		if existing.Name == provider.Name {
			return fmt.Errorf("global provider %q already exists", provider.Name)
		}
	}
	cfg.Providers = append(cfg.Providers, provider)
	return saveConfig(cfg)
}

// UpdateGlobalProvider replaces an existing global provider by name.
func UpdateGlobalProvider(name string, provider ProviderConfig) error {
	configMu.Lock()
	defer configMu.Unlock()
	cfg, err := loadLocked()
	if err != nil {
		return err
	}
	for i := range cfg.Providers {
		if cfg.Providers[i].Name == name {
			provider.Name = name // name is immutable in update
			cfg.Providers[i] = provider

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check existence first (load config, scan cfg.Providers for the name) and update or skip instead of adding
  2. Remove the existing global provider via the corresponding remove API, then re-add with the new settings
  3. Give the new provider a distinct name if both definitions are genuinely needed

Example fix

// before
if err := config.AddGlobalProvider(provider); err != nil { return err }
// after (idempotent)
if err := config.AddGlobalProvider(provider); err != nil {
    if strings.Contains(err.Error(), "already exists") { return nil }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

cfg, _ := config.Load()
for _, ex := range cfg.Providers {
    if ex.Name == provider.Name { return nil } // already registered
}

Try / catch

if err := config.AddGlobalProvider(provider); err != nil {
    if strings.Contains(err.Error(), "already exists") {
        return nil // idempotent bootstrap
    }
    return err
}

Prevention

When it happens

Trigger: Calling the add-global-provider function when cfg.Providers already contains an entry with existing.Name == provider.Name — re-running setup, retry after an earlier successful add, or two workers adding the same default provider concurrently (the mutex prevents races, not repeats).

Common situations: Bootstrap script adding a default global provider on every run; user re-invoking an 'add global provider' command; migrating configs where the provider was already copied into the global section.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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