paperclipai/paperclip · error · Error

Worktree config already exists at ${paths.configPath} or ins

Error message

Worktree config already exists at ${paths.configPath} or instance data exists at ${paths.instanceRoot}. Re-run with --force to replace it.

What it means

Thrown by runWorktreeInit when EITHER the target config path OR the instance data root already exists and --force was not supplied. This protects against clobbering an existing worktree instance (its config.json, env file, and the isolated home dir under ~/.paperclip/instances/<id>). The check fires before any write so existing state is preserved.

Source

Thrown at cli/src/commands/worktree.ts:1643

  const seedMode = opts.seedMode ?? "minimal";
  if (!isWorktreeSeedMode(seedMode)) {
    throw new Error(`Unsupported seed mode "${seedMode}". Expected one of: minimal, full.`);
  }
  const instanceId = sanitizeWorktreeInstanceId(opts.instance ?? worktreeName);
  const paths = resolveWorktreeLocalPaths({
    cwd,
    homeDir: resolveWorktreeHome(opts.home),
    instanceId,
  });
  const branding = {
    name: opts.name ?? worktreeName,
    color: opts.color ?? generateWorktreeColor(),
  };
  const sourceConfigPath = resolveSourceConfigPath(opts);
  const sourceConfig = existsSync(sourceConfigPath) ? readConfig(sourceConfigPath) : null;

  if ((existsSync(paths.configPath) || existsSync(paths.instanceRoot)) && !opts.force) {
    throw new Error(
      `Worktree config already exists at ${paths.configPath} or instance data exists at ${paths.instanceRoot}. Re-run with --force to replace it.`,
    );
  }

  if (opts.force) {
    // Only remove the specific files we're about to rewrite, not the whole
    // repoConfigDir — that directory can contain sibling state such as
    // <repo>/.paperclip/worktrees/ holding every repo-managed worktree
    // checkout, and a recursive rmSync here would nuke them all.
    rmSync(paths.configPath, { force: true });
    rmSync(paths.envPath, { force: true });
    const seedMarkers = resolveWorktreeSeedMarkerPaths(paths.configPath);
    rmSync(seedMarkers.pending, { force: true });
    rmSync(seedMarkers.complete, { force: true });
    rmSync(paths.instanceRoot, { recursive: true, force: true });
  }

  const claimedPorts = collectClaimedWorktreePorts(paths.homeDir, paths.instanceId, paths.cwd);

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. If the existing instance is disposable, re-run with --force to replace the config, env, seed markers, and instance root.
  2. If you want to keep it, use a different --instance <id> or --name.
  3. Clean up first: `paperclipai worktree:clean <name>` then re-init.
  4. Inspect the paths in the error message to decide which is the stale one before forcing.

Example fix

// before
paperclipai worktree:init --instance feat-a
# error: config/instance already exists
// after (intentional replacement)
paperclipai worktree:init --instance feat-a --force
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from "node:fs";

function requireCleanTarget(paths: { configPath: string; instanceRoot: string }, force: boolean): void {
  if (force) return;
  if (existsSync(paths.configPath) || existsSync(paths.instanceRoot)) {
    throw new Error(`Worktree already exists; pass --force or clean first.`);
  }
}

Type guard

function worktreeTargetOccupied(paths: { configPath: string; instanceRoot: string }): boolean {
  return existsSync(paths.configPath) || existsSync(paths.instanceRoot);
}

Try / catch

try { await runWorktreeInit(opts); }
catch (err) {
  if (/already exists/.test(String((err as Error).message))) {
    opts.force = true; // or prompt user
    await runWorktreeInit(opts);
  } else throw err;
}

Prevention

When it happens

Trigger: Running `worktree:init` twice with the same instance id/name; an earlier init crashed mid-way leaving config.json or the instance dir behind; re-running after a partial failure without cleaning up; using the same --instance id across two worktrees.

Common situations: Developer iterates on worktree setup and forgets the previous init succeeded partially; CI re-runs a job on the same runner without cleanup; two terminals init the same instance name.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/77cfd8afe88d1ac0. Report an issue: GitHub.