{"record":{"id":"fcd3b0e86dfa496b","repo":"chenhg5/cc-connect","slug":"provider-q-already-exists-in-project-q","errorCode":null,"errorMessage":"provider %q already exists in project %q","messagePattern":"provider %q already exists in project %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1320,"sourceCode":"\tdefer configMu.Unlock()\n\tif ConfigPath == \"\" {\n\t\treturn fmt.Errorf(\"config path not set\")\n\t}\n\tdata, err := os.ReadFile(ConfigPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read config: %w\", err)\n\t}\n\tcfg := &Config{}\n\tif err := toml.Unmarshal(data, cfg); err != nil {\n\t\treturn fmt.Errorf(\"parse config: %w\", err)\n\t}\n\n\tfound := false\n\tfor i := range cfg.Projects {\n\t\tif cfg.Projects[i].Name == projectName {\n\t\t\tfor _, existing := range cfg.Projects[i].Agent.Providers {\n\t\t\t\tif existing.Name == provider.Name {\n\t\t\t\t\treturn fmt.Errorf(\"provider %q already exists in project %q\", provider.Name, projectName)\n\t\t\t\t}\n\t\t\t}\n\t\t\tcfg.Projects[i].Agent.Providers = append(cfg.Projects[i].Agent.Providers, provider)\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !found {\n\t\treturn fmt.Errorf(\"project %q not found in config\", projectName)\n\t}\n\treturn saveConfig(cfg)\n}\n\n// RemoveProviderFromConfig removes a provider from a project's agent config and saves.\n// For global providers referenced via provider_refs, it removes the reference\n// instead of deleting the global definition.\nfunc RemoveProviderFromConfig(projectName, providerName string) error {\n\tconfigMu.Lock()","sourceCodeStart":1302,"sourceCodeEnd":1338,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1302-L1338","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nif err := config.AddProviderToConfig(\"proj\", provider); err != nil { return err }\n// after (idempotent)\nif err := config.AddProviderToConfig(\"proj\", provider); err != nil {\n    if !strings.Contains(err.Error(), \"already exists\") { return err }\n    // already present — treat as success\n}","handlingStrategy":"try-catch","validationCode":"cfg, _ := config.Load()\nfor _, pr := range cfg.Projects {\n    if pr.Name == projectName {\n        for _, ex := range pr.Agent.Providers {\n            if ex.Name == provider.Name { return nil } // already added\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := config.AddProviderToConfig(project, provider); err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        return nil // idempotent add\n    }\n    return err\n}","preventionTips":["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)"],"tags":["go","config","duplicate","validation"],"backgroundTag":"file-already-exists","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}