alibaba/open-code-review · error

provider %q already exists

Error message

provider %q already exists

What it means

When saving an edited or newly created custom provider, the chosen provider name collides with an existing entry that is not the one being edited. Since custom providers are keyed by name, allowing the save would silently overwrite the other provider's settings, so the save is rejected with the conflicting name quoted.

Source

Thrown at cmd/opencodereview/provider_tui.go:1381

	// Optional fields are always applied so users can intentionally clear them.
	// To detect "user cleared the API key" vs "user left it masked/untouched",
	// apiKey is only overwritten when the user actively typed something.
	entry.URL = r.url
	entry.Protocol = r.protocol
	entry.AuthHeader = r.authHeader
	if key, edited := m.customAPIKeyForSave(); edited {
		entry.APIKey = key
	}
	// Switching an entry to an ambient protocol drops the key it no longer uses,
	// rather than leaving a live credential in a file nothing reads it from.
	if entry.Protocol == llm.ProtocolAnthropicBedrock {
		entry.APIKey = ""
	}
	// If name changed, delete old key
	if r.editTargetName != "" && r.editTargetName != r.provider {
		if _, exists := m.existingCfg.CustomProviders[r.provider]; exists {
			m.formError = fmt.Sprintf(`Provider "%s" already exists`, r.provider)
			return fmt.Errorf("provider %q already exists", r.provider)
		}
		delete(m.existingCfg.CustomProviders, r.editTargetName)
		if m.existingCfg.Provider == r.editTargetName {
			m.existingCfg.Provider = r.provider
			m.existingCfg.Model = ""
		}
	}
	m.existingCfg.CustomProviders[r.provider] = entry

	if err := saveConfig(m.configPath, m.existingCfg); err != nil {
		m.formError = fmt.Sprintf("failed to save: %v", err)
		if reloaded, reloadErr := loadOrCreateConfig(m.configPath); reloadErr == nil {
			m.existingCfg = reloaded
			m.customProviders = collectCustomProviders(reloaded)
		} else {
			m.existingCfg.CustomProviders = backupProviders
			m.existingCfg.Provider = backupActiveProvider
			m.existingCfg.Model = backupActiveModel

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Choose a different provider name; the name collides with an existing entry in the config
  2. If you meant to modify the existing provider, use the edit flow instead of the add flow
  3. Check existing entries (including built-in provider names) before adding a custom provider
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at cmd/opencodereview/provider_tui.go:1381 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/f827f714b40751e8. Report an issue: GitHub.