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] = providerView on GitHub (pinned to 4000b2338a)
Solutions
- Check existence first (load config, scan cfg.Providers for the name) and update or skip instead of adding
- Remove the existing global provider via the corresponding remove API, then re-add with the new settings
- 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
- Gate global-provider bootstrap on a 'already initialized' marker rather than re-adding
- Use upsert semantics where the API allows update-on-existing
- Serialize bootstrap steps so two workers cannot both attempt the same add
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
- provider %q already exists in project %q
- tmux: 'session' option is required (name of the tmux session
- config: relay.visibility must be "full", "summary", or "none
- config: at least one [[projects]] entry is required
- config: %s.name is required
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/25e324d2807a1ed8.
Report an issue: GitHub.