chenhg5/cc-connect · error
provider %q already exists in project %q
Error message
provider %q already exists in project %q
What it means
AddProviderToConfig found an existing provider with the same name in the target project's agent.providers and returns this duplicate-name error instead of silently overwriting. Provider names are treated as unique keys within a project.
Source
Thrown at config/config.go:1320
defer configMu.Unlock()
if ConfigPath == "" {
return fmt.Errorf("config path not set")
}
data, err := os.ReadFile(ConfigPath)
if err != nil {
return fmt.Errorf("read config: %w", err)
}
cfg := &Config{}
if err := toml.Unmarshal(data, cfg); err != nil {
return fmt.Errorf("parse config: %w", err)
}
found := false
for i := range cfg.Projects {
if cfg.Projects[i].Name == projectName {
for _, existing := range cfg.Projects[i].Agent.Providers {
if existing.Name == provider.Name {
return fmt.Errorf("provider %q already exists in project %q", provider.Name, projectName)
}
}
cfg.Projects[i].Agent.Providers = append(cfg.Projects[i].Agent.Providers, provider)
found = true
break
}
}
if !found {
return fmt.Errorf("project %q not found in config", projectName)
}
return saveConfig(cfg)
}
// RemoveProviderFromConfig removes a provider from a project's agent config and saves.
// For global providers referenced via provider_refs, it removes the reference
// instead of deleting the global definition.
func RemoveProviderFromConfig(projectName, providerName string) error {
configMu.Lock()View on GitHub (pinned to 4000b2338a)
Solutions
- Use the corresponding update/rename API instead of add, or remove the existing provider first via config.RemoveProviderFromConfig
- Check existence before adding (load config, scan providers for the name) and skip or update on match
- Pick a different provider name if the intent is a second, distinct provider
Example fix
// before
if err := config.AddProviderToConfig("proj", provider); err != nil { return err }
// after (idempotent)
if err := config.AddProviderToConfig("proj", provider); err != nil {
if !strings.Contains(err.Error(), "already exists") { return err }
// already present — treat as success
} Defensive patterns
Strategy: try-catch
Validate before calling
cfg, _ := config.Load()
for _, pr := range cfg.Projects {
if pr.Name == projectName {
for _, ex := range pr.Agent.Providers {
if ex.Name == provider.Name { return nil } // already added
}
}
} Try / catch
if err := config.AddProviderToConfig(project, provider); err != nil {
if strings.Contains(err.Error(), "already exists") {
return nil // idempotent add
}
return err
} Prevention
- Make add-provider commands idempotent (skip or update on duplicate)
- Use update/rename APIs when settings change instead of add
- Generate unique provider names in scripts (suffix with env/region)
When it happens
Trigger: Calling config.AddProviderToConfig(projectName, provider) where any cfg.Projects[i].Agent.Providers entry already has existing.Name == provider.Name — e.g. re-running an add command, retry after a partial failure, or a script that adds providers unconditionally.
Common situations: Idempotency gap in setup scripts run twice; user re-issuing an 'add provider' command in the bot; importing the same provider definition into a project that already has it.
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
- global provider %q already exists
- 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/fcd3b0e86dfa496b.
Report an issue: GitHub.