paperclipai/paperclip · error · Error

Explicit source Paperclip config does not match the register

Error message

Explicit source Paperclip config does not match the registered base project workspace.

What it means

An explicit --from-config was supplied AND the base workspace declares its own config; the resolver canonicalizes both and they must be the same physical file. If they differ, the explicit source contradicts the registered workspace, and seeding from it would bypass the workspace's own instance identity.

Source

Thrown at packages/shared/src/worktree-seed-source.ts:162

      ? path.join(canonicalBaseCwd, ".paperclip", "config.json")
      : null;
  }

  const selectedPath = registeredConfigPath ?? explicitSource;
  if (!selectedPath) {
    throw new Error(
      "Registered base project workspace has no Paperclip config of its own and no explicit source was provided.",
    );
  }
  const canonicalSourceConfigPath = canonicalRegularFile(selectedPath, "Registered source Paperclip config");
  if (registeredConfigPath && canonicalSourceConfigPath !== registeredConfigPath) {
    throw new Error("Registered source Paperclip config escapes the base project workspace or uses a symlink alias.");
  }

  if (explicitSource) {
    const canonicalExplicitSource = canonicalRegularFile(explicitSource, "Explicit source Paperclip config");
    if (canonicalExplicitSource !== canonicalSourceConfigPath) {
      throw new Error("Explicit source Paperclip config does not match the registered base project workspace.");
    }
  }

  const canonicalTargetConfigPath = canonicalRegularFile(
    input.targetConfigPath,
    "Target worktree Paperclip config",
  );
  if (canonicalSourceConfigPath === canonicalTargetConfigPath) {
    throw new Error("Source and target Paperclip configs are the same canonical file.");
  }

  const sourceInstanceId = readInstanceId(canonicalSourceConfigPath, "source");
  const targetInstanceId = readInstanceId(canonicalTargetConfigPath, "target");
  if (targetInstanceId !== input.expectedTargetInstanceId) {
    throw new Error("Target Paperclip instance does not match the registered worktree instance.");
  }
  if (sourceInstanceId === targetInstanceId) {
    throw new Error("Source and target Paperclip configs name the same instance.");

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Compare the two paths after realpath: the explicit source must equal `<base>/.paperclip/config.json`.
  2. Drop the `--from-config` flag and let the registered workspace supply the source.
  3. Or point `--from-config` exactly at the workspace's own config file (`"$(realpath <base>/.paperclip/config.json)"`).

Example fix

# before
paperclip worktree seed --from-config ~/.paperclip/instances/other/config.json   # in a workspace with its own .paperclip

# after
paperclip worktree seed   # registered workspace's own config is the source
Defensive patterns

Strategy: validation

Validate before calling

import { realpathSync } from "node:fs";
import path from "node:path";

if (registeredCwd && explicitSource && baseWorkspaceDeclaresInstanceConfig(registeredCwd)) {
  const own = path.join(registeredCwd, ".paperclip", "config.json");
  if (realpathSync(explicitSource) !== realpathSync(own)) {
    throw new Error("--from-config conflicts with the workspace's own config; omit it");
  }
}

Prevention

When it happens

Trigger: resolveRegisteredWorktreeSeedSource with both registeredBaseWorkspaceCwd (declaring `.paperclip/config.json`) and explicitSourceConfigPath pointing at any other config file — different instance root, another checkout's config, or an older copy.

Common situations: Scripts hardcoding --from-config while the workspace later got its own config; operators pointing --from-config at `~/.paperclip/instances/<id>/config.json` when the workspace's local config is the registered source; copy-pasted flags from another workspace's docs.

Related errors


AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21). Data as JSON: /api/errors/131583f5d7643511. Report an issue: GitHub.