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

  1. Use the corresponding update/rename API instead of add, or remove the existing provider first via config.RemoveProviderFromConfig
  2. Check existence before adding (load config, scan providers for the name) and skip or update on match
  3. 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

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


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