paperclipai/paperclip · error
Invalid running embedded database port
Error message
Invalid running embedded database port
What it means
Thrown by create-auth-bootstrap-invite when line 4 of the embedded PostgreSQL postmaster.pid file (the TCP port postmaster is listening on) is not an integer in the valid port range 1-65535. The script trusts this line to build the postgres:// connection URL for the embedded database, so an unusable port means the pid file is stale, corrupt, or from a layout it does not understand, and it aborts instead of connecting to the wrong instance.
Solutions
- Confirm the embedded database is running for this exact data directory (start it with `pnpm dev`) so a complete postmaster.pid exists
- Delete the stale/truncated postmaster.pid and restart the embedded database so it regenerates a full pid file
- Reset the embedded data directory if it is expendable: `rm -rf data/pglite && pnpm dev`, then rerun the script
- Switch the config to database.mode "postgres" with a connectionString to bypass pid-file parsing entirely
Example fix
// inspect the pid file
// cat ./data/pglite/postmaster.pid # line 1=PID, 2=datadir, 4=port
// before (config.json)
{ "database": { "mode": "embedded", "embeddedPostgresDataDir": "./stale-dir" } }
// after
{ "database": { "mode": "embedded", "embeddedPostgresDataDir": "./data/pglite" } } Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from "node:fs";
const pidLines = readFileSync(`${dataDir}/postmaster.pid`, "utf8").split(/\r?\n/);
const port = Number(pidLines[3]);
if (!Number.isInteger(port) || port < 1 || port > 65535) {
throw new Error(`postmaster.pid line 4 is not a valid port: ${pidLines[3]}`);
} Type guard
function isValidPort(v: unknown): v is number {
return typeof v === "number" && Number.isInteger(v) && v >= 1 && v <= 65535;
} Try / catch
try {
await runBootstrapInvite(configPath, baseUrl);
} catch (err) {
if (err instanceof Error && err.message === "Invalid running embedded database port") {
// pid file truncated/stale: restart embedded postgres, then retry
await restartEmbeddedPostgres(dataDir);
await runBootstrapInvite(configPath, baseUrl);
} else throw err;
} Prevention
- Verify the pid file has at least 5 lines before relying on it (cat <dataDir>/postmaster.pid)
- Point embeddedPostgresDataDir at the live data directory the server actually uses
- Avoid copying data directories while the postmaster is running; stop it first
- Prefer database.mode=postgres + connectionString when you do not depend on embedded Postgres
When it happens
Trigger: Running the bootstrap script in embedded mode (config.database.mode !== "postgres") where <embeddedPostgresDataDir>/postmaster.pid has fewer than 5 lines (so pidLines[3] is undefined) or a fourth line that Number() cannot turn into an integer between 1 and 65535.
Common situations: Embedded Postgres crashed mid-write leaving a truncated pid file; the data directory belongs to an older/different PostgreSQL layout; a leftover pid file from an instance that already exited; pointing embeddedPostgresDataDir at a partially initialized or manually copied directory.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Embedded bootstrap data directory does not match the…
- Embedded bootstrap requires its configured data directory
- Invalid embedded postmaster PID
- Could not resolve database connection from
- database-contract-unmet
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/044c96a4ace7c353.
Report an issue: GitHub.
Appendix: source
Thrown at packages/db/scripts/create-auth-bootstrap-invite.ts:50
mode?: string;
embeddedPostgresPort?: number;
embeddedPostgresDataDir?: string;
connectionString?: string;
};
};
// The server can select another port when the configured one is occupied.
// Bind bootstrap to this data directory's running process, never another instance.
let embeddedPort: number | undefined;
if (config.database?.mode !== "postgres") {
const dataDir = config.database?.embeddedPostgresDataDir;
if (!dataDir) throw new Error("Embedded bootstrap requires its configured data directory");
const pidLines = readFileSync(path.join(dataDir, "postmaster.pid"), "utf8").split(/\r?\n/);
if (realpathSync(pidLines[1] ?? "") !== realpathSync(dataDir)) throw new Error("Embedded bootstrap data directory does not match the running postmaster");
const postmasterPid = Number(pidLines[0]);
if (!Number.isInteger(postmasterPid) || postmasterPid <= 1) throw new Error("Invalid embedded postmaster PID");
process.kill(postmasterPid, 0);
embeddedPort = Number(pidLines[3]);
if (!Number.isInteger(embeddedPort) || embeddedPort < 1 || embeddedPort > 65535) throw new Error("Invalid running embedded database port");
}
const dbUrl =
config.database?.mode === "postgres"
? config.database.connectionString
: `postgres://paperclip:paperclip@127.0.0.1:${embeddedPort}/paperclip`;
if (!dbUrl) {
throw new Error(`Could not resolve database connection from ${configPath}`);
}
const db = createDb(dbUrl);
const closableDb = db as typeof db & {
$client?: {
end?: (options?: { timeout?: number }) => Promise<void>;
};
};
try {
const now = new Date();View on GitHub (pinned to 3f1d897a7c)