ultraworkers/claw-code · error · std::io::Error
agent_already_exists
agent_already_exists
Error message
agent_already_exists: agent '{name}' already exists at {} What it means
Thrown by `create_agent` when the `/agents create <name>` slash command finds that `<cwd>/.claw/agents/<name>.toml` already exists (commands/src/lib.rs:3818). The collision check uses the SANITIZED name — lowercased, restricted to a-z, 0-9, '-', '_', '.' — so two differently-typed names that sanitize identically collide on the same file. Returned as `io::ErrorKind::AlreadyExists` from the command handler.
Source
Thrown at rust/crates/commands/src/lib.rs:3822
}
names.sort();
Ok(names)
}
fn create_agent(name: &str, cwd: &Path) -> std::io::Result<CreatedAgent> {
let Some(name) = sanitize_skill_invocation_name(name) else {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"invalid_agent_name: agent name must contain at least one alphanumeric character",
));
};
let root = cwd.join(".claw").join("agents");
let path = root.join(format!("{name}.toml"));
if path.exists() {
return Err(std::io::Error::new(
std::io::ErrorKind::AlreadyExists,
format!(
"agent_already_exists: agent '{name}' already exists at {}",
path.display()
),
));
}
fs::create_dir_all(&root)?;
fs::write(
&path,
format!(
"name = \"{name}\"\ndescription = \"Describe when to use this agent.\"\nmodel_reasoning_effort = \"medium\"\n"
),
)?;
Ok(CreatedAgent { name, path })
}
fn default_skill_install_root() -> std::io::Result<PathBuf> {
if let Ok(claw_config_home) = env::var("CLAW_CONFIG_HOME") {View on GitHub (pinned to 08106b0c37)
Solutions
- Pick a different agent name whose sanitized form differs (check `.claw/agents/` for the exact colliding file shown in the message).
- If the existing agent is stale, delete or edit `.claw/agents/<name>.toml` directly and re-run the command.
- List existing agents first (`/agents`) before creating to avoid the collision.
Example fix
# before /agents create reviewer # agent_already_exists: 'reviewer' already exists at .claw/agents/reviewer.toml # after (pick a name that does not collide after sanitization) ls .claw/agents /agents create reviewer-2
Defensive patterns
Strategy: validation
Validate before calling
fn agent_toml_path(name: &str, cwd: &Path) -> PathBuf {
cwd.join(".claw").join("agents").join(format!("{name}.toml"))
}
// before create_agent:
if agent_toml_path(raw_name, cwd).exists() { /* pick another name or edit it */ } Try / catch
if let Err(e) = create_agent(name, cwd) {
if e.kind() == std::io::ErrorKind::AlreadyExists {
// name collision after sanitization: offer to edit existing .claw/agents/<name>.toml
} else { return Err(e); }
} Prevention
- List `.claw/agents/` before creating
- Remember names are sanitized (lowercase, [a-z0-9-_.]) so 'Code Review' and 'code-review' collide
- Commit or deliberately gitignore `.claw/agents/` so team collisions are visible
When it happens
Trigger: Running `/agents create reviewer` twice in the same workspace; creating `Code Review` after `code-review` (both sanitize to `code-review`); a stale `.claw/agents/<name>.toml` left behind by a previous session or teammate.
Common situations: Re-running workspace bootstrap scripts that create agents; teammates committing `.claw/agents/` to the repo; case/punctuation variants of an existing agent name silently mapping to the same sanitized file.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
AI-assisted analysis of ultraworkers/claw-code@08106b0c37 (2026-08-18).
Data as JSON: /api/errors/f8ada781f5171c1c.
Report an issue: GitHub.