paperclipai/paperclip · error · Error

Resolved worktree path ${directPath} does not contain .paper

Error message

Resolved worktree path ${directPath} does not contain .paperclip/config.json.

What it means

Thrown by resolveWorktreeEndpointFromSelector when the selector resolves to an existing directory (existsSync true) but that directory has no .paperclip/config.json. Because the path exists as a real directory, the resolver treats it as a direct path target — and requires a Paperclip config inside it. Without the config it cannot be a merge/seed endpoint.

Source

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

  const allowCurrent = opts?.allowCurrent !== false;
  if (trimmed.length === 0) {
    throw new Error("Worktree selector cannot be empty.");
  }

  const currentEndpoint = resolveCurrentWorktreeEndpoint();
  if (allowCurrent && trimmed === "current") {
    return currentEndpoint;
  }

  const choices = toMergeSourceChoices(process.cwd());
  const directPath = path.resolve(trimmed);
  if (existsSync(directPath)) {
    if (allowCurrent && directPath === currentEndpoint.rootPath) {
      return currentEndpoint;
    }
    const configPath = path.resolve(directPath, ".paperclip", "config.json");
    if (!existsSync(configPath)) {
      throw new Error(`Resolved worktree path ${directPath} does not contain .paperclip/config.json.`);
    }
    return {
      rootPath: directPath,
      configPath,
      label: path.basename(directPath),
      isCurrent: false,
    };
  }

  const matched = choices.find((choice) =>
    (allowCurrent || !choice.isCurrent)
    && (choice.worktree === directPath
      || path.basename(choice.worktree) === trimmed
      || choice.branchLabel === trimmed),
  );
  if (!matched) {
    throw new Error(
      `Could not resolve worktree "${selector}". Use a path, a listed worktree directory name, branch name, or "current".`,

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Initialize Paperclip in that directory first: `cd <path> && paperclipai worktree:init`.
  2. Point the selector at a directory that already has .paperclip/config.json (run `worktree:list` to find valid ones).
  3. If you meant a branch/dir NAME rather than a path, ensure the value doesn't resolve to an existing config-less directory.

Example fix

// before
paperclipai worktree:merge-history --source /path/to/plain-worktree
# /path/to/plain-worktree has no .paperclip/config.json
// after
cd /path/to/plain-worktree && paperclipai worktree:init
paperclipai worktree:merge-history --source /path/to/plain-worktree
Defensive patterns

Strategy: validation

Validate before calling

const cfgPath = path.resolve(directPath, ".paperclip", "config.json");
if (!existsSync(cfgPath)) throw new Error(`${directPath} is not a Paperclip worktree; run worktree:init`);

Type guard

function dirIsPaperclipWorktree(dir: string): boolean {
  return existsSync(path.resolve(dir, ".paperclip", "config.json"));
}

Try / catch

try { resolveWorktreeEndpointFromSelector(selector); }
catch (err) {
  if (/does not contain .paperclip\/config.json/.test(String((err as Error).message))) {
    // init Paperclip there, or pick a different selector
  } else throw err;
}

Prevention

When it happens

Trigger: Passing a path to a plain git worktree that was never initialized as a Paperclip worktree; pointing at an arbitrary directory; the .paperclip dir was deleted from an otherwise valid worktree.

Common situations: Created a git worktree manually (`git worktree add`) without running `worktree:init`; wrong directory passed as source; .paperclip wiped by git clean.

Related errors


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