paperclipai/paperclip · error · Error

Registered ${label} Paperclip config is missing its adjacent

Error message

Registered ${label} Paperclip config is missing its adjacent .env instance pointer.

What it means

Thrown by readInstanceId in worktree-seed-source.ts while resolving the registered source/target Paperclip config: the config's directory has no adjacent .env file, and the layout is not an instance-root config (whose parent directory is named "instances" and which identifies the instance by its own directory name). Worktree configs always ship an .env instance pointer, so its absence means a malformed or partially copied config.

Source

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

};

export type RegisteredWorktreeSeedSourceInput = {
  registeredBaseWorkspaceCwd?: string | null;
  explicitSourceConfigPath?: string | null;
  targetConfigPath: string;
  expectedTargetInstanceId: string;
};

function readInstanceId(configPath: string, label: "source" | "target"): string {
  const configDir = path.dirname(configPath);
  const envPath = path.join(configDir, ".env");
  if (!existsSync(envPath)) {
    // An instance-root config (`<home>/instances/<id>/config.json`) names its instance
    // by directory rather than by an adjacent .env; worktree configs always ship one.
    if (path.basename(path.dirname(configDir)) === "instances") {
      return resolvePaperclipInstanceId(path.basename(configDir));
    }
    throw new Error(`Registered ${label} Paperclip config is missing its adjacent .env instance pointer.`);
  }
  const contents = readFileSync(envPath, "utf8");
  for (const rawLine of contents.split(/\r?\n/)) {
    const match = rawLine.match(
      /^\s*(?:export\s+)?PAPERCLIP_INSTANCE_ID\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s#]+))/,
    );
    const value = (match?.[1] ?? match?.[2] ?? match?.[3] ?? "").trim();
    if (value) return value;
  }
  throw new Error(`Registered ${label} Paperclip config has no PAPERCLIP_INSTANCE_ID binding.`);
}

function errorCode(error: unknown): string {
  return (error as NodeJS.ErrnoException | null)?.code ?? "unknown error";
}

/**
 * Inspect a directory entry without following it, returning null only when it is absent.

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Create the missing .env next to config.json with a PAPERCLIP_INSTANCE_ID=<id> line (use the instance id of the Paperclip instance this config belongs to).
  2. Prefer the instance-root layout <home>/instances/<id>/config.json, which needs no .env (the directory names the instance).
  3. If the worktree setup was interrupted, re-run the worktree creation flow so it regenerates .env.
  4. Check your sync/clean tooling (.gitignore rules, workspace cleaners) is not deleting the adjacent .env.

Example fix

# before: <worktree>/.paperclip/config.json exists, no <worktree>/.paperclip/.env

# after: create <worktree>/.paperclip/.env
PAPERCLIP_INSTANCE_ID=inst_01J8ZQ...
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from "node:fs";
import path from "node:path";
function configHasInstancePointer(configPath: string): boolean {
  const dir = path.dirname(configPath);
  return existsSync(path.join(dir, ".env")) ||
    path.basename(path.dirname(dir)) === "instances";
}

Try / catch

try {
  resolveRegisteredWorktreeSeedSource(input);
} catch (error) {
  if (error instanceof Error && error.message.includes("missing its adjacent .env instance pointer")) {
    // create <configDir>/.env with PAPERCLIP_INSTANCE_ID=<id>, then retry
  }
  throw error;
}

Prevention

When it happens

Trigger: resolveRegisteredWorktreeSeedSource reads the source or target config.json, looks for .env in the same directory, does not find it, and path.basename(dirname(configDir)) !== "instances" — e.g. a worktree whose .env was never generated, or a config.json copied to a new location without its .env.

Common situations: Copying just config.json into a new checkout or dotfiles sync that skips .env files; a partially created worktree (interrupted setup); moving a workspace directory and losing the adjacent .env; git operations that clean ignored files (.env is typically ignored) after the config was committed.

Related errors


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