{"record":{"id":"6210c8ae44a6bfe2","repo":"can1357/oh-my-pi","slug":"no-backups-found-in-dir","errorCode":null,"errorMessage":"No backups found in ${dir}","messagePattern":"No backups found in (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"packages/mnemopi/src/dr/recovery.ts","lineNumber":300,"sourceCode":"\t\t\t\t// Preserve the restore failure.\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t}\n}\nexport function emergencyRestore(backupDir?: string | null, dbPath?: string | null): EmergencyRestoreResult {\n\tconst paths = getDefaultPaths();\n\tconst dir = backupDir ?? paths.backupDir;\n\tconst targetPath = dbPath ?? paths.dbPath;\n\tconst backups = existsSync(dir)\n\t\t? readdirSync(dir)\n\t\t\t\t.filter(name => /^mnemopi_backup_.*\\.db\\.gz$/.test(name))\n\t\t\t\t.sort()\n\t\t\t\t.reverse()\n\t\t\t\t.map(name => join(dir, name))\n\t\t: [];\n\n\tif (backups.length === 0) throw new FileNotFoundError(`No backups found in ${dir}`);\n\n\tlet attempts = 0;\n\tfor (const backup of backups) {\n\t\tattempts += 1;\n\t\ttry {\n\t\t\tconst result = restoreBackup(backup, targetPath);\n\t\t\tif (result.integrity_check) return { restored: true, backup_used: backup, attempts };\n\t\t} catch {\n\t\t\t// Try the next backup, matching the Python recovery behavior.\n\t\t}\n\t}\n\tthrow new Error(\"All backups failed integrity check\");\n}\nexport function verifyIntegrity(dbPath?: string | null): boolean {\n\tconst targetPath = dbPath ?? getDefaultPaths().dbPath;\n\tif (!existsSync(targetPath)) return false;\n\n\tlet db: Database | null = null;","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/mnemopi/src/dr/recovery.ts#L282-L318","documentation":"emergencyRestore() scans the given directory for files matching the backup naming pattern (mnemopi_backup_*.db.gz). If no matching files exist it throws FileNotFoundError naming the directory. It refuses to proceed rather than silently leaving a missing/corrupt database in place.","triggerScenarios":"Calling emergencyRestore(dir, targetPath) where dir contains no files matching /^mnemopi_backup_.*\\.db\\.gz$/ (either the directory is empty/missing or backups were renamed).","commonSituations":"Pointing emergencyRestore at the wrong directory, backups stored with a custom naming scheme that breaks the regex, backups pruned by a retention job, or a typo in the dir path / wrong environment (staging vs prod).","solutions":["List the directory and confirm mnemopi_backup_*.db.gz files exist; fix the dir path if wrong.","Rename existing backup files to match the expected pattern, e.g. mv backup.db.gz mnemopi_backup_2026-08-31.db.gz.","Generate a new backup with backupDatabase() into the expected directory, then retry.","If no backups exist anywhere, restore from external/offsite copies before running emergencyRestore."],"exampleFix":"// before\nawait emergencyRestore('/var/data/wrong-dir', dbPath);\n// after\nimport { readdirSync } from 'node:fs';\nconst dir = '/var/backups/mnemopi';\nconst hasBackups = readdirSync(dir).some(n => /^mnemopi_backup_.*\\.db\\.gz$/.test(n));\nif (!hasBackups) throw new Error(`No mnemopi backups in ${dir}; check path`);\nawait emergencyRestore(dir, dbPath);","handlingStrategy":"validation","validationCode":"import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nfunction findBackups(dir) {\n  if (!existsSync(dir)) return [];\n  return readdirSync(dir)\n    .filter(name => /^mnemopi_backup_.*\\.db\\.gz$/.test(name))\n    .map(name => join(dir, name));\n}\nif (findBackups(dir).length === 0) {\n  throw new Error(`emergencyRestore: no mnemopi_backup_*.db.gz in ${dir}`);\n}\nawait emergencyRestore(dir, targetPath);","typeGuard":"function hasBackupDir(dir) {\n  return typeof dir === 'string' && dir.length > 0 && existsSync(dir);\n}","tryCatchPattern":"try {\n  await emergencyRestore(dir, targetPath);\n} catch (err) {\n  if (err instanceof FileNotFoundError && String(err).includes('No backups found')) {\n    console.error(`Check backup dir (got: ${dir}); expected mnemopi_backup_*.db.gz files`);\n  } else throw err;\n}","preventionTips":["Verify the backup directory path in config per environment","Keep the canonical mnemopi_backup_ naming scheme — never rename backup files","Monitor backup dir contents so retention jobs don't empty it","Alert when the newest backup is older than a threshold"],"tags":["backup-restore","file-not-found","disaster-recovery","configuration"],"backgroundTag":"no-backups-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}