paperclipai/paperclip · critical

The running embedded PostgreSQL identity does not match…

Error message

The running embedded PostgreSQL identity does not match this instance. Startup stopped before connecting.

What it means

embeddedPostgresOwnerPort reads the embedded PostgreSQL postmaster PID file and returns the actual port the running instance is listening on after collision avoidance. Before returning, it verifies that the PID, data directory, and port recorded in the file match the current instance's expected PID and dataDir. Any mismatch or out-of-range port means the running PostgreSQL belongs to a different instance, so startup is stopped before connecting to avoid operating on a foreign database.

Solutions

  1. Stop the other running Paperclip/PostgreSQL process, then remove the stale postmaster.pid from the data directory before restarting
  2. Point this instance at its own data directory (or reset dev DB with `rm -rf data/pglite` and `pnpm dev`)
  3. If the PID file is corrupt (port NaN), delete the pid file only after confirming no postgres process is alive (`ps aux | grep postgres`)
  4. Run each instance from a distinct workspace/checkout so data dirs do not collide

Example fix

# before: stale pid file from another instance
rm -rf data/pglite && pnpm dev
Defensive patterns

Strategy: try-catch

Validate before calling

const contents = fs.readFileSync(postmasterPidFile, "utf8");
const [pid, dir, , port] = contents.split("\n");
const ok = Number(pid) === expectedPid && dir && resolve(dir) === resolve(dataDir)
  && Number.isSafeInteger(Number(port)) && Number(port) >= 1 && Number(port) <= 65535;
if (!ok) console.error("pid file identity mismatch — clean up before starting");

Type guard

function pidFileMatches(contents: string, dataDir: string, expectedPid: number): boolean {
  const [pid, directory, , portText] = contents.split("\n");
  const port = Number(portText);
  return Number(pid) === expectedPid && Boolean(directory)
    && resolve(directory) === resolve(dataDir)
    && Number.isSafeInteger(port) && port >= 1 && port <= 65535;
}

Try / catch

try { port = embeddedPostgresOwnerPort(contents, dataDir, expectedPid); }
catch (e) {
  console.error("Embedded PostgreSQL identity mismatch; stop the other instance and clear the stale postmaster.pid", e);
  process.exit(1);
}

Prevention

When it happens

Trigger: Calling startServerWithDatabaseTeardown when a postmaster.pid file exists but records a different PID than expected, a data directory path that resolves elsewhere than the configured dataDir, or a port outside 1-65535 (including NaN from a corrupt/truncated pid file).

Common situations: Copying or restoring a data/ directory while another Paperclip instance is still running; a stale or hand-edited postmaster.pid; running two instances against the same checkout after a crash; Docker volume reuse across differently-configured containers.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/afa6edcd821b29b7. Report an issue: GitHub.

Appendix: source

Thrown at server/src/embedded-postgres-owner.ts:10

import { resolve } from "node:path";

/** postmaster.pid records the actual listening port, which can differ from the
 * configured port after collision avoidance. Never reuse the configured port. */
export function embeddedPostgresOwnerPort(contents: string, dataDir: string, expectedPid: number): number {
  const [pid, directory, , portText] = contents.split("\n");
  const port = Number(portText);
  if (Number(pid) !== expectedPid || !directory || resolve(directory) !== resolve(dataDir) ||
      !Number.isSafeInteger(port) || port < 1 || port > 65535)
    throw new Error("The running embedded PostgreSQL identity does not match this instance. Startup stopped before connecting.");
  return port;
}

View on GitHub (pinned to 3f1d897a7c)