paperclipai/paperclip · error · Error

test-drive cannot reuse a data directory configured for an e

Error message

test-drive cannot reuse a data directory configured for an external PostgreSQL database. Choose a fresh data directory or change database.mode to embedded-postgres.

What it means

After re-registering both old and new endpoints during a warm transition, the transport verifies the NEW registered connection is connect-mode AND canonically identical to the connection recorded in the warm-recovery proof receipt. A mode mismatch or any canonical-JSON difference between the registered connection and the receipt throws this error, since the proof would no longer cover the actual endpoint.

Source

Thrown at cli/src/commands/test-drive.ts:216

  return { dataDir, linkedWorktree };
}

export function assertTestDriveDatabaseIsolation(
  configPath?: string,
  env: NodeJS.ProcessEnv = process.env,
  readConfigFile: (path?: string) => PaperclipConfig | null = readConfig,
): void {
  if (env.DATABASE_URL?.trim() || env.DATABASE_MIGRATION_URL?.trim()) {
    throw new Error(
      "test-drive requires its isolated embedded database. Remove DATABASE_URL and " +
        "DATABASE_MIGRATION_URL from the selected data directory's .env, or choose a fresh --data-dir.",
    );
  }

  const config = readConfigFile(configPath);
  if (config?.database.mode === "postgres") {
    throw new Error(
      "test-drive cannot reuse a data directory configured for an external PostgreSQL database. " +
        "Choose a fresh data directory or change database.mode to embedded-postgres.",
    );
  }
}

export function resolveTestDriveBootstrap(
  options: TestDriveOptions,
  env: NodeJS.ProcessEnv = process.env,
): ResolvedTestDriveBootstrap {
  if (options.apiKey !== undefined && options.apiKeyEnv !== undefined) {
    throw new Error("--api-key and --api-key-env are mutually exclusive.");
  }

  const harness = options.harness ?? "claude";
  const definition = HARNESS_DEFINITIONS[harness];
  if (!definition) {
    throw new Error(`Unsupported test-drive harness: ${String(harness)}.`);

View on GitHub (pinned to 01ad858492)

Solutions

  1. Make the registration return exactly the endpoint recorded in the warm-recovery proof receipt (byte-for-byte canonical JSON equal).
  2. Re-issue the warm-recovery proof/receipt if the endpoint legitimately changed, so the receipt matches the new connection.
  3. Check for proxies/control-plane middleware that mutates the registered connection and disable or fix it.

Example fix

// before
receipt.connection = { mode: "connect", connectUrl: "http://127.0.0.1:9100" };
registered = { mode: "connect", connectUrl: "http://localhost:9100/" }; // mismatch
// after
registered = { mode: "connect", connectUrl: "http://127.0.0.1:9100" }; // canonical match
Defensive patterns

Strategy: validation

Validate before calling

const canonical = (v: unknown) => JSON.stringify(v, Object.keys((v as object)).sort());
if (canonical(newConnection) !== canonical(receipt.connection)) {
  throw new Error("registered connection does not match recovery receipt");
}

Type guard

function matchesReceipt(conn: unknown, receipt: { connection: unknown }): boolean {
  return JSON.stringify(conn) === JSON.stringify(receipt.connection);
}

Try / catch

try {
  await transport.startTurn(input);
} catch (e) {
  if (e.message === "native_runner_warm_transition_registered_endpoint_mismatch") {
    await requestNewWarmRecoveryProof(root, desiredIdentity); // refresh receipt to current endpoint
  }
}

Prevention

When it happens

Trigger: `controlPlaneRegistration` returns a connection whose `mode` is not "connect", or whose canonical JSON differs from `warmRecovery.proof.receipt.connection` (different URL, port, or extra fields).

Common situations: The control plane rewrites or normalizes the URL (adds/removes a trailing slash, swaps host) between registration and the receipt; a load balancer or proxy changes the advertised endpoint; a stale receipt from a previous identity being replayed.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/0f2e4c303e6e80c3. Report an issue: GitHub.