{"record":{"id":"a93459db2f95e37f","repo":"mastra-ai/mastra","slug":"failed-to-swap-compacted-copy-into-place-and-faile","errorCode":null,"errorMessage":"Failed to swap compacted copy into place AND failed to restore the original — your data is intact at ${file}.old; rename it back to ${file} manually. Original error: ${err instanceof Error ? err.message : String(err)}","messagePattern":"Failed to swap compacted copy into place AND failed to restore the original — your data is intact at (.+?)\\.old; rename it back to (.+?) manually\\. Original error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"mastracode/sdk/src/utils/storage-maintenance.ts","lineNumber":234,"sourceCode":"      throw new Error(\n        `${file} was opened by another process during compaction — is another Mastra Code session running? ` +\n          `Close other sessions and run /prune vacuum again.`,\n      );\n    }\n    // Swap the compacted copy into place. The old WAL/SHM sidecars belong to\n    // the old inode — they must never be paired with the new file. If any step\n    // after the first rename fails, restore the original so the db path is\n    // never left empty (a naive restart would otherwise create a fresh db).\n    renameSync(file, `${file}.old`);\n    try {\n      rmSync(`${file}-wal`, { force: true });\n      rmSync(`${file}-shm`, { force: true });\n      renameSync(tmp, file);\n    } catch (err) {\n      try {\n        renameSync(`${file}.old`, file);\n      } catch {\n        throw new Error(\n          `Failed to swap compacted copy into place AND failed to restore the original — ` +\n            `your data is intact at ${file}.old; rename it back to ${file} manually. ` +\n            `Original error: ${err instanceof Error ? err.message : String(err)}`,\n        );\n      }\n      rmSync(tmp, { force: true });\n      throw err;\n    }\n    rmSync(`${file}.old`, { force: true });\n    results.push({ file, bytesBefore, bytesAfter: fileSizeWithWal(file) });\n  }\n  return results;\n}\n\n/** `file:/path` or `file:///path` → filesystem path; undefined for non-file urls. */\nfunction fileUrlToPath(url: string): string | undefined {\n  if (!url.startsWith('file:')) return undefined;\n  return url.replace(/^file:\\/\\//, '').replace(/^file:/, '');","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/utils/storage-maintenance.ts#L216-L252","documentation":"During the final swap, the original file is renamed to `.old` and the compacted copy is renamed into place. If the swap fails AND restoring the original back from `${file}.old` also fails, this error is thrown. It guarantees the user that their data is still intact at `${file}.old` and instructs them to rename it back manually.","triggerScenarios":"renameSync fails twice in a row — e.g. the volume went read-only or full, the directory permissions changed, a file watcher holds the path open on a platform where renames over open files fail (Windows), or the .old restore path is unavailable.","commonSituations":"Disk-full or read-only filesystem hit mid-swap; Windows antivirus/indexer locking the file during renames; NFS/network volumes with weak rename semantics; permission changes during a long vacuum.","solutions":["Manually restore: `mv <file>.old <file>` — the data is intact there","Check volume free space and writability (`df -h`, `mount | grep ro`) before retrying, then re-run /prune vacuum","On Windows/NFS, retry the vacuum from a local filesystem where renames are atomic"],"exampleFix":"// manual recovery shell\nmv mastra.db.old mastra.db\nrm -f mastra.db.tmp  # if a leftover compacted copy exists","handlingStrategy":"try-catch","validationCode":"import { accessSync, constants } from 'node:fs';\n// Verify the directory is writable and has space before attempting a swap\naccessSync(dirname(dbFile), constants.W_OK);\nconst { bsize, bavail } = statfsSync(dirname(dbFile));\nif (bsize * bavail < statSync(dbFile).size) throw new Error('Insufficient space/permissions for compaction swap');","typeGuard":null,"tryCatchPattern":"try {\n  await maintenance.results();\n} catch (e) {\n  if (String(e.message).includes('your data is intact at') && String(e.message).includes('.old')) {\n    console.error('Recovering: renaming <db>.old back to <db>');\n    renameSync(`${dbFile}.old`, dbFile);\n  } else throw e;\n}","preventionTips":["Run vacuums on local (not NFS/network) filesystems where renames are reliable","Ensure free disk space and writability before starting","On Windows, exclude the db from antivirus/indexing that can lock files during renames","Keep the .old file until you've verified the compacted db opens"],"tags":["sqlite","filesystem","data-loss-risk","rename"],"backgroundTag":"file-rename-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}