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
- Make the registration return exactly the endpoint recorded in the warm-recovery proof receipt (byte-for-byte canonical JSON equal).
- Re-issue the warm-recovery proof/receipt if the endpoint legitimately changed, so the receipt matches the new connection.
- 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
- Issue recovery receipts from the same registration path that returns the connection so they cannot diverge.
- Disable proxies/middleware that rewrite registered endpoints.
- Compare endpoints with canonical JSON before attempting warm transitions.
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
- test-drive requires its isolated embedded database. Remove D
- --api-key and --api-key-env are mutually exclusive.
- Unsupported test-drive harness: ${String(harness)}.
- Installing or updating Paperclip requires Node.js ${MINIMUM_
- Paperclip returned no result while ${action}.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/0f2e4c303e6e80c3.
Report an issue: GitHub.