nikivdev/code · warning

Tool '{}' already exists

Error message

Tool '{}' already exists

What it means

Raised by new_tool (src/tools.rs:158) when scaffolding a tool whose target file <tools_dir>/<name>.ts already exists. The scaffold step refuses to overwrite an existing tool to avoid destroying user code.

Source

Thrown at src/tools.rs:158

        .status()
        .context("failed to run bun")?;

    if !status.success() {
        bail!("Tool '{}' exited with status: {}", name, status);
    }

    Ok(())
}

/// Create a new tool.
fn new_tool(name: &str, description: Option<&str>, use_ai: bool) -> Result<()> {
    let tools_dir = get_tools_dir()?;
    fs::create_dir_all(&tools_dir).context("failed to create tools directory")?;

    let tool_file = tools_dir.join(format!("{}.ts", name));

    if tool_file.exists() {
        bail!("Tool '{}' already exists", name);
    }

    if use_ai {
        // Use localcode to generate the tool
        let localcode = find_localcode();
        if localcode.is_none() {
            bail!(
                "localcode not found. Install it with:\n  \
                 cd <opencode-repo> && flow link"
            );
        }

        let desc = description.unwrap_or(name);
        let prompt = format!(
            "Create a TypeScript tool for Bun called '{}' that: {}\n\n\
             Requirements:\n\
             - Use Bun APIs (Bun.$, Bun.file, etc.)\n\
             - Add a description comment at the top\n\

View on GitHub (pinned to a747e741ae)

Solutions

  1. If regeneration is intended, delete or rename the existing <tools_dir>/<name>.ts first, then re-run `f tools new <name>`.
  2. If the tool already exists, just use it — no need to scaffold again.
  3. Choose a different name if you meant to create a distinct tool.
  4. Guard setup scripts: skip `tools new` if the .ts file already exists.

Example fix

// before: naive setup script
f tools new deploy
// after: idempotent
[ -f "$TOOLS_DIR/deploy.ts" ] || f tools new deploy
Defensive patterns

Strategy: validation

Validate before calling

const fs = require("fs");
const toolFile = path.join(toolsDir, name + ".ts");
if (fs.existsSync(toolFile)) {
  console.error(`tool ${name} already exists at ${toolFile}; skipping scaffold`);
}

Try / catch

try {
  newTool(name);
} catch (e) {
  if (String(e).includes("already exists")) {
    console.error("edit the existing tool instead of re-scaffolding");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `f tools new <name>` when a tool with that name was already created — e.g. re-running an init script twice, or intentionally trying to regenerate a tool that exists.

Common situations: Idempotent setup scripts re-invoked on an already-configured machine; name collision with an existing tool; forgetting the tool was created earlier in the session.

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 nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/798bbf6e844e46a4. Report an issue: GitHub.