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
- Use the update/edit path instead of create when modifying an existing profile.
- Delete or rename the existing profile with that ID in `settings.json` before re-creating it.
- Generate a fresh unique ID for the new profile instead of reusing the colliding one.
- 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
- Branch create-vs-update on `contains_key` before saving.
- Derive profile IDs from stable unique names to avoid collisions.
- Disable double-submit on profile forms in the UI.
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
- Cannot list directory because its path matches the user's wo
- Cannot list directory because its path matches the user's wo
- Cannot read file because its path matches the global `file_s
- Cannot read file because its path matches the global `privat
- Cannot read file because its path matches the worktree `file
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/a4a35c166016e6d1.
Report an issue: GitHub.