paperclipai/paperclip · error · Error

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

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.

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.

Appendix: 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)