paperclipai/paperclip · error · Error

Registered ${label} Paperclip config has no PAPERCLIP_INSTAN

Error message

Registered ${label} Paperclip config has no PAPERCLIP_INSTANCE_ID binding.

What it means

Thrown by readInstanceId in worktree-seed-source.ts when the .env adjacent to a registered Paperclip config exists but contains no parseable PAPERCLIP_INSTANCE_ID assignment. The parser accepts optional `export`, double/single quotes, and unquoted values, but a file with only other variables (or only commented-out lines) yields no identity, and the resolver refuses to guess which instance the config belongs to.

Source

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

  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.
 *
 * Any other failure means the declared path is unreadable or malformed, and a guess there
 * would silently seed from a different instance.
 */
function inspectDeclaredEntry(entryPath: string, configPath: string, detail?: string): Stats | null {
  try {
    return lstatSync(entryPath);
  } catch (error) {
    if (errorCode(error) === "ENOENT") return null;
    throw new Error(

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Add a line PAPERCLIP_INSTANCE_ID=<your-instance-id> to the .env next to config.json.
  2. Uncomment the existing line if it is commented, and fix the exact spelling PAPERCLIP_INSTANCE_ID.
  3. Verify with a quick grep: grep -n 'PAPERCLIP_INSTANCE_ID' <configDir>/.env must print exactly one assignment.
  4. If you do not know the instance id, read it from the instance-root directory name (<home>/instances/<id>) or the Paperclip server config.

Example fix

# before (.paperclip/.env)
# PAPERCLIP_INSTANCE_ID=inst_old
PAPERCLIP_API_URL=http://localhost:3100

# after
PAPERCLIP_INSTANCE_ID=inst_01J8ZQ...
PAPERCLIP_API_URL=http://localhost:3100
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync, existsSync } from "node:fs";
import path from "node:path";
function envBindsInstanceId(configPath: string): boolean {
  const envPath = path.join(path.dirname(configPath), ".env");
  if (!existsSync(envPath)) return false;
  return /^\s*(?:export\s+)?PAPERCLIP_INSTANCE_ID\s*=/m.test(readFileSync(envPath, "utf8"));
}

Try / catch

try {
  resolveRegisteredWorktreeSeedSource(input);
} catch (error) {
  if (error instanceof Error && error.message.includes("no PAPERCLIP_INSTANCE_ID binding")) {
    // append PAPERCLIP_INSTANCE_ID=<id> to <configDir>/.env, then retry
  }
  throw error;
}

Prevention

When it happens

Trigger: resolveRegisteredWorktreeSeedSource finds <configDir>/.env, reads it line by line, and no line matches PAPERCLIP_INSTANCE_ID=... — e.g. an .env holding only PAPERCLIP_API_URL, or PAPERCLIP_INSTANCE_ID commented out with '#'.

Common situations: Template .env files shipped with placeholders commented out; hand-edited .env where the variable was renamed (INSTANCE_ID, PAPERCLIP_ID); whitespace/typo variants the regex does not cover (missing '=', typo in the name); multiple config copies sharing a generic .env.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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