{"record":{"id":"d4563819fac8e694","repo":"paperclipai/paperclip","slug":"embedded-bootstrap-requires-its-configured-data-directory","errorCode":null,"errorMessage":"Embedded bootstrap requires its configured data directory","messagePattern":"Embedded bootstrap requires its configured data directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/db/scripts/create-auth-bootstrap-invite.ts","lineNumber":43,"sourceCode":"\n  if (!configPath || !baseUrl) {\n    throw new Error(\"Usage: tsx create-auth-bootstrap-invite.ts --config <path> --base-url <url>\");\n  }\n\n  const config = JSON.parse(readFileSync(path.resolve(configPath), \"utf8\")) as {\n    database?: {\n      mode?: string;\n      embeddedPostgresPort?: number;\n      embeddedPostgresDataDir?: string;\n      connectionString?: string;\n    };\n  };\n  // The server can select another port when the configured one is occupied.\n  // Bind bootstrap to this data directory's running process, never another instance.\n  let embeddedPort: number | undefined;\n  if (config.database?.mode !== \"postgres\") {\n    const dataDir = config.database?.embeddedPostgresDataDir;\n    if (!dataDir) throw new Error(\"Embedded bootstrap requires its configured data directory\");\n    const pidLines = readFileSync(path.join(dataDir, \"postmaster.pid\"), \"utf8\").split(/\\r?\\n/);\n    if (realpathSync(pidLines[1] ?? \"\") !== realpathSync(dataDir)) throw new Error(\"Embedded bootstrap data directory does not match the running postmaster\");\n    const postmasterPid = Number(pidLines[0]);\n    if (!Number.isInteger(postmasterPid) || postmasterPid <= 1) throw new Error(\"Invalid embedded postmaster PID\");\n    process.kill(postmasterPid, 0);\n    embeddedPort = Number(pidLines[3]);\n    if (!Number.isInteger(embeddedPort) || embeddedPort < 1 || embeddedPort > 65535) throw new Error(\"Invalid running embedded database port\");\n  }\n  const dbUrl =\n    config.database?.mode === \"postgres\"\n      ? config.database.connectionString\n      : `postgres://paperclip:paperclip@127.0.0.1:${embeddedPort}/paperclip`;\n  if (!dbUrl) {\n    throw new Error(`Could not resolve database connection from ${configPath}`);\n  }\n\n  const db = createDb(dbUrl);\n  const closableDb = db as typeof db & {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/db/scripts/create-auth-bootstrap-invite.ts#L25-L61","documentation":"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.","triggerScenarios":"Running create-auth-bootstrap-invite.ts with config.database.mode !== \"postgres\" and no config.database.embeddedPostgresDataDir set.","commonSituations":"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.","solutions":["Set config.database.embeddedPostgresDataDir to the running instance's data directory (e.g. data/pglite).","Ensure the dev server (embedded DB) has been started at least once so the directory and postmaster.pid exist.","If you actually use an external Postgres, run in postgres mode instead (set mode: \"postgres\")."],"exampleFix":"// before\n// config: { database: { mode: \"embedded\" } }\n// after\n// config: { database: { mode: \"embedded\", embeddedPostgresDataDir: \"data/pglite\" } }","handlingStrategy":"validation","validationCode":"if (config.database?.mode !== \"postgres\" && !config.database?.embeddedPostgresDataDir) {\n  throw new Error(\"set database.embeddedPostgresDataDir before running bootstrap\");\n}","typeGuard":null,"tryCatchPattern":"try { await main(); } catch (e) {\n  if (e.message.includes(\"requires its configured data directory\")) { console.error(\"point config.database.embeddedPostgresDataDir at the running dev instance\"); }\n  throw e;\n}","preventionTips":["Start the dev server once so the embedded data dir and postmaster.pid exist","Keep embeddedPostgresDataDir set in every config used with bootstrap scripts","Use postgres mode explicitly when targeting external Postgres","Document the required config key next to the script invocation"],"tags":["database","embedded-postgres","bootstrap","config"],"backgroundTag":"missing-required-config-field","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}