paperclipai/paperclip · error · Error

Source and target Paperclip configs are the same. Choose dif

Error message

Source and target Paperclip configs are the same. Choose different --from/--to worktrees.

What it means

Thrown by worktreeMergeHistoryCommand after resolving both endpoints when path.resolve(sourceEndpoint.configPath) === path.resolve(targetEndpoint.configPath). Merging a worktree into itself is a no-op at best and corrupts counts at worst, so the CLI refuses. The check is on the config file path, meaning two different selectors that resolve to the same worktree (e.g. --from current --to current, or a branch name whose worktree is the current checkout) trip it.

Source

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

  if (opts.apply && opts.dry) {
    throw new Error("Use either --apply or --dry, not both.");
  }

  if (sourceArg && opts.from) {
    throw new Error("Use either the positional source argument or --from, not both.");
  }

  const targetEndpoint = opts.to
    ? resolveWorktreeEndpointFromSelector(opts.to, { allowCurrent: true })
    : resolveCurrentWorktreeEndpoint();
  const sourceEndpoint = opts.from
    ? resolveWorktreeEndpointFromSelector(opts.from, { allowCurrent: true })
    : sourceArg
      ? resolveWorktreeEndpointFromSelector(sourceArg, { allowCurrent: true })
      : await promptForSourceEndpoint(targetEndpoint.rootPath);

  if (path.resolve(sourceEndpoint.configPath) === path.resolve(targetEndpoint.configPath)) {
    throw new Error("Source and target Paperclip configs are the same. Choose different --from/--to worktrees.");
  }

  const scopes = parseWorktreeMergeScopes(opts.scope);
  const sourceHandle = await openConfiguredDb(sourceEndpoint.configPath);
  const targetHandle = await openConfiguredDb(targetEndpoint.configPath);
  const sourceStorages = resolveAttachmentLookupStorages({
    sourceEndpoint,
    targetEndpoint,
  });
  const targetStorage = openConfiguredStorage(targetEndpoint.configPath);

  try {
    const company = await resolveMergeCompany({
      sourceDb: sourceHandle.db,
      targetDb: targetHandle.db,
      selector: opts.company,
    });
    let collected = await collectMergePlan({

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Set --to explicitly to a different worktree: `paperclipai worktree:merge-history --from current --to <other>`.
  2. If you only have one instance, use `worktree reseed` with a different source config instead.

Example fix

// before
paperclipai worktree:merge-history --from current
// after
paperclipai worktree:merge-history --from current --to /path/to/target-worktree --apply
Defensive patterns

Strategy: validation

Validate before calling

import path from "node:path";

function validateDistinctEndpoints(sourceConfigPath: string, targetConfigPath: string): void {
  if (path.resolve(sourceConfigPath) === path.resolve(targetConfigPath)) {
    throw new Error("Source and target Paperclip configs are the same. Choose different --from/--to worktrees.");
  }
}

Prevention

When it happens

Trigger: Calling merge-history where --from and --to resolve to the same worktree: omitting both (both default to current), passing --from current with default --to, or passing a branch/dir selector that points at the current checkout.

Common situations: A developer forgets to set --to and the default (current) happens to equal --from. Or they pass --from <branch> where <branch> is checked out in the current worktree.

Related errors


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