paperclipai/paperclip · error

Embedded bootstrap requires its configured data directory

Error message

Embedded bootstrap requires its configured data directory

What it means

The bootstrap-invite script binds to the already-running embedded (PGlite/embedded-postgres) instance so it talks to the exact database process for the configured data directory. In non-postgres mode it requires config.database.embeddedPostgresDataDir; without it there is no way to locate the running postmaster or its port, so the script throws. This prevents creating a bootstrap invite against the wrong or a fresh database.

Solutions

  1. Set config.database.embeddedPostgresDataDir to the running instance's data directory (e.g. data/pglite).
  2. Ensure the dev server (embedded DB) has been started at least once so the directory and postmaster.pid exist.
  3. If you actually use an external Postgres, run in postgres mode instead (set mode: "postgres").

Example fix

// before
// config: { database: { mode: "embedded" } }
// after
// config: { database: { mode: "embedded", embeddedPostgresDataDir: "data/pglite" } }
Defensive patterns

Strategy: validation

Validate before calling

if (config.database?.mode !== "postgres" && !config.database?.embeddedPostgresDataDir) {
  throw new Error("set database.embeddedPostgresDataDir before running bootstrap");
}

Try / catch

try { await main(); } catch (e) {
  if (e.message.includes("requires its configured data directory")) { console.error("point config.database.embeddedPostgresDataDir at the running dev instance"); }
  throw e;
}

Prevention

When it happens

Trigger: Running create-auth-bootstrap-invite.ts with config.database.mode !== "postgres" and no config.database.embeddedPostgresDataDir set.

Common situations: Pointing the script at a config file that only has postgres settings; running the script before ever starting the dev server so no data dir exists; typo'd config key for the data dir.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at packages/db/scripts/create-auth-bootstrap-invite.ts:43

  if (!configPath || !baseUrl) {
    throw new Error("Usage: tsx create-auth-bootstrap-invite.ts --config <path> --base-url <url>");
  }

  const config = JSON.parse(readFileSync(path.resolve(configPath), "utf8")) as {
    database?: {
      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 & {

View on GitHub (pinned to 3f1d897a7c)