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

  1. Pick a different agent name whose sanitized form differs (check `.claw/agents/` for the exact colliding file shown in the message).
  2. If the existing agent is stale, delete or edit `.claw/agents/<name>.toml` directly and re-run the command.
  3. 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

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.