{"record":{"id":"397b106036b04f08","repo":"can1357/oh-my-pi","slug":"database-not-found-sourcepath","errorCode":null,"errorMessage":"Database not found: ${sourcePath}","messagePattern":"Database not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"packages/mnemopi/src/dr/recovery.ts","lineNumber":149,"sourceCode":"\tconst explicit = env.MNEMOPI_BACKUP_DIR;\n\tif (explicit !== undefined && explicit.length > 0) return explicit;\n\tconst dir = configuredDataDir(env);\n\treturn join(dirname(dir), \"backups\");\n}\n\nexport function getDefaultPaths(env: Env = process.env): RecoveryPaths {\n\treturn {\n\t\tdataDir: configuredDataDir(env),\n\t\tbackupDir: defaultBackupDir(env),\n\t\tdbPath: configuredDbPath(env),\n\t};\n}\nexport function createBackup(dbPath?: string | null, backupDir?: string | null): BackupResult {\n\tconst paths = getDefaultPaths();\n\tconst sourcePath = dbPath ?? paths.dbPath;\n\tconst destinationDir = backupDir ?? paths.backupDir;\n\n\tif (!existsSync(sourcePath)) throw new FileNotFoundError(`Database not found: ${sourcePath}`);\n\n\tmkdirSync(destinationDir, { recursive: true });\n\tconst timestamp = timestampForBackup();\n\n\tlet snapshot: Uint8Array | null = null;\n\tlet sourceDb: Database | null = null;\n\ttry {\n\t\tsourceDb = openDatabase(sourcePath, { create: false, readwrite: false, pragmas: false });\n\t\tsnapshot = (sourceDb as SerializableDatabase).serialize();\n\t} finally {\n\t\tcloseQuietly(sourceDb);\n\t}\n\tif (snapshot === null) throw new Error(`Unable to serialize database backup: ${sourcePath}`);\n\tconst backupPath = writeBackupFile(destinationDir, timestamp, gzipSync(snapshot));\n\n\tconst dbBytes = readFileSync(sourcePath);\n\tconst backupBytes = readFileSync(backupPath);\n\tconst metadata: BackupMetadata = {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/mnemopi/src/dr/recovery.ts#L131-L167","documentation":"createBackup snapshots the SQLite database at sourcePath (falling back to the configured default db path). Before doing anything it checks existence and throws FileNotFoundError when the source database file is missing, so a backup is never created from a nonexistent database.","triggerScenarios":"createBackup(path) with a typo'd or moved db file; calling backup before the database was ever created (fresh install); pointing at the wrong environment's path (staging vs prod); dbPath param explicitly null while the default path doesn't exist.","commonSituations":"First run before any write created the db; container/volume remounts losing the data dir; relative vs absolute path confusion after changing working directory; deleted db while the app was stopped.","solutions":["Verify the db file exists at the path (ls / existsSync) and fix the path argument","Create/initialize the database first (open it once so the file exists), then back up","Check MNEMOPI config/default paths — pass an explicit dbPath rather than relying on defaults"],"exampleFix":"// before\ncreateBackup(\"./data/memry.db\"); // typo\n// after\nconst dbPath = \"./data/memory.db\";\nif (!existsSync(dbPath)) throw new Error(`db missing: ${dbPath}`);\ncreateBackup(dbPath, backupDir);","handlingStrategy":"validation","validationCode":"import { existsSync } from \"node:fs\";\nfunction safeCreateBackup(dbPath, backupDir) {\n\tif (!existsSync(dbPath)) throw new Error(`refusing backup: db missing at ${dbPath}`);\n\treturn createBackup(dbPath, backupDir);\n}","typeGuard":null,"tryCatchPattern":"try {\n\tcreateBackup(dbPath, backupDir);\n} catch (err) {\n\tif (err.name === \"FileNotFoundError\" && err.message.startsWith(\"Database not found\")) {\n\t\tinitDatabase(dbPath); // create + seed the db, then retry once\n\t\tcreateBackup(dbPath, backupDir);\n\t} else throw err;\n}","preventionTips":["Resolve db paths to absolute paths once at startup","Initialize the database before enabling backup jobs","Validate configured paths exist at boot","Use try/catch with isEnoent rather than manual existence checks when reading"],"tags":["filesystem","backup","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}