Hmbown/CodeWhale · error
duplicate agent profile id {}
Error message
duplicate agent profile id {} What it means
load_agent_profiles_from_dir loads every *.toml in the profile directory and enforces unique profile ids, compared case-insensitively via to_ascii_lowercase. A second file claiming an already-seen id bails, because worker profiles are addressed by id and a duplicate would make selection ambiguous.
Source
Thrown at crates/tui/src/fleet/profile.rs:287
pub fn load_agent_profile_identities_from_dir(
dir: impl AsRef<Path>,
) -> Result<Vec<AgentProfileIdentity>> {
let dir = dir.as_ref();
agent_profile_paths(dir)?
.into_iter()
.map(|path| load_agent_profile_identity_file(&path))
.collect()
}
pub fn load_agent_profiles_from_dir(dir: impl AsRef<Path>) -> Result<Vec<AgentProfile>> {
let dir = dir.as_ref();
let mut profiles = Vec::new();
let mut seen = BTreeSet::new();
for path in agent_profile_paths(dir)? {
let profile = load_agent_profile_file(&path)?;
if !seen.insert(profile.id.to_ascii_lowercase()) {
bail!("duplicate agent profile id {}", profile.id);
}
profiles.push(profile);
}
Ok(profiles)
}
fn agent_profile_paths(dir: &Path) -> Result<Vec<PathBuf>> {
if !dir.exists() {
return Ok(Vec::new());
}
if !dir.is_dir() {
bail!("agent profile path {} is not a directory", dir.display());
}
let mut paths = std::fs::read_dir(dir)
.with_context(|| format!("reading agent profile dir {}", dir.display()))?
.collect::<std::io::Result<Vec<_>>>()
.with_context(|| format!("reading agent profile entries in {}", dir.display()))?View on GitHub (pinned to 0c42157ee5)
Solutions
- List ids across profile TOMLs in the directory (grep '^id') and rename or remove the duplicate
- Remember the check is case-insensitive: 'Coder' and 'coder' collide
- Keep one profile per file and name files after their id to prevent recurrence
Example fix
# before: profiles/coder.toml -> id = "coder"; profiles/coder-alt.toml -> id = "Coder" # after: profiles/coder.toml -> id = "coder"; profiles/reviewer.toml -> id = "reviewer"
Defensive patterns
Strategy: validation
Validate before calling
use std::collections::BTreeSet;
fn profile_ids_unique(paths: &[std::path::PathBuf]) -> Result<(), String> {
let mut seen = BTreeSet::new();
for p in paths {
let id = read_profile_id(p)?; // parse `id = "..."`
if !seen.insert(id.to_ascii_lowercase()) {
return Err(format!("duplicate profile id {id} in {}", p.display()));
}
}
Ok(())
} Try / catch
if let Err(err) = load_agent_profiles_from_dir(&dir) {
if err.to_string().contains("duplicate agent profile id") {
eprintln!("two profile TOMLs share an id (case-insensitive); rename one");
}
return Err(err.into());
} Prevention
- Name each profile file after its id and keep one profile per file
- Check ids case-insensitively when syncing profiles from multiple machines
- Run a duplicate-id lint in CI for checked-in profile directories
When it happens
Trigger: Two TOML files in the agent profile dir (including subdirectory-style names differing only by case or extension spelling) whose id fields lowercase to the same value, e.g. "Reviewer" and "reviewer".
Common situations: Copying a profile file to tweak it and forgetting to change id; case-only rename left behind on case-insensitive filesystems; syncing profiles from two machines into one dir.
Related errors
- agent profile path {} is not a directory
- agent profile {} tools.posture={other:?} would widen permiss
- agent profile {} may not request allow_shell=true
- agent profile {} may not request trust=true
- Codewhale-owned credential file {} exceeds the {} byte safet
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/d4ee1a0f2db1ef73.
Report an issue: GitHub.