zed-industries/zed · error · anyhow::Error

profile with ID '{profile_id}' already exists

Error message

profile with ID '{profile_id}' already exists

What it means

`AgentProfile::save_to_settings` inserts a new profile into `SettingsContent.agent.profiles` and first checks `profiles.contains_key(&profile_id.0)`. Creating a profile with an ID that already exists bails with this message rather than overwriting, so the settings file never loses data implicitly.

Source

Thrown at crates/agent_settings/src/agent_profile.rs:163

    pub fn is_context_server_tool_enabled(&self, server_id: &str, tool_name: &str) -> bool {
        self.context_servers
            .get(server_id)
            .and_then(|preset| preset.tools.get(tool_name).copied())
            .unwrap_or(self.enable_all_context_servers)
    }

    pub fn save_to_settings(
        &self,
        profile_id: AgentProfileId,
        content: &mut SettingsContent,
    ) -> Result<()> {
        let profiles = content
            .agent
            .get_or_insert_default()
            .profiles
            .get_or_insert_default();
        if profiles.contains_key(&profile_id.0) {
            bail!("profile with ID '{profile_id}' already exists");
        }

        profiles.insert(
            profile_id.0,
            AgentProfileContent {
                name: self.name.clone().into(),
                tools: self.tools.clone(),
                enable_all_context_servers: Some(self.enable_all_context_servers),
                context_servers: self
                    .context_servers
                    .clone()
                    .into_iter()
                    .map(|(server_id, preset)| {
                        (
                            server_id,
                            ContextServerPresetContent {
                                tools: preset.tools,
                            },

View on GitHub (pinned to f4178619ac)

Solutions

  1. Use the update/edit path instead of create when modifying an existing profile.
  2. Delete or rename the existing profile with that ID in `settings.json` before re-creating it.
  3. Generate a fresh unique ID for the new profile instead of reusing the colliding one.
  4. Pre-check `content.agent.profiles.contains_key(&id)` before calling `save_to_settings` and branch to update vs create.

Example fix

// before — unconditional create
current_profile.save_to_settings(profile_id.clone(), &mut content)?;

// after — create only when absent, else update
if content.agent.as_ref()
    .and_then(|agent| agent.profiles.as_ref())
    .map_or(false, |profiles| profiles.contains_key(&profile_id.0))
{
    current_profile.update_in_settings(profile_id, &mut content)?; // existing entry
} else {
    current_profile.save_to_settings(profile_id, &mut content)?;    // new entry
}
Defensive patterns

Strategy: validation

Validate before calling

let exists = content.agent.as_ref()
    .and_then(|agent| agent.profiles.as_ref())
    .map_or(false, |profiles| profiles.contains_key(&profile_id.0));
if exists {
    // take the update path instead of save_to_settings
}

Type guard

fn profile_id_is_free(content: &SettingsContent, id: &AgentProfileId) -> bool {
    content.agent.as_ref()
        .and_then(|agent| agent.profiles.as_ref())
        .map_or(true, |profiles| !profiles.contains_key(&id.0))
}

Try / catch

match profile.save_to_settings(id.clone(), &mut content) {
    Err(e) if e.to_string().contains("already exists") => {
        // load and update the existing profile instead of duplicating
    }
    rest => rest,
}

Prevention

When it happens

Trigger: Calling profile-creation flow (e.g. the agent configuration UI's save) twice with the same `AgentProfileId`, or programmatically calling `save_to_settings` with an ID already present in `settings.json`'s `agent.profiles` map.

Common situations: Double-submitting the profile form; retrying a save after an unclear error; two team members syncing a settings file that already contains the same profile ID.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/a4a35c166016e6d1. Report an issue: GitHub.