mastra-ai/mastra · error
${file} was opened by another process during compaction — is
Error message
${file} was opened by another process during compaction — is another Mastra Code session running? Close other sessions and run /prune vacuum again. What it means
VACUUM INTO can take tens of seconds on large databases. After compaction finishes and before swapping the compacted copy into place, reclaimLibSQLDisk re-probes the journal-mode header. If it is no longer 'delete', a new session opened the database in WAL mode during the vacuum window; swapping under it would orphan that session's inode and silently lose its writes, so the tool deletes the temp copy and aborts.
Source
Thrown at mastracode/sdk/src/utils/storage-maintenance.ts:216
`Not enough free disk space to compact ${file}: need ${formatBytes(requiredFreeBytes(liveBytes))} ` +
`for a ${formatBytes(liveBytes)} compacted copy, but only ${formatBytes(freeBytes)} is free.`,
);
}
onFileStart?.(file, bytesBefore, liveBytes);
db.exec(`VACUUM INTO '${tmp.replace(/'/g, "''")}'`);
} catch (err) {
rmSync(tmp, { force: true });
throw err;
} finally {
db.close();
}
// Re-probe right before the swap: `VACUUM INTO` can take tens of seconds
// on multi-GB files, and a session started in that window reopens the db
// in WAL mode (flipping the header back). Swapping under it would orphan
// that session's inode and silently lose its writes.
if (journalModeFromHeader(file) !== 'delete') {
rmSync(tmp, { force: true });
throw new Error(
`${file} was opened by another process during compaction — is another Mastra Code session running? ` +
`Close other sessions and run /prune vacuum again.`,
);
}
// Swap the compacted copy into place. The old WAL/SHM sidecars belong to
// the old inode — they must never be paired with the new file. If any step
// after the first rename fails, restore the original so the db path is
// never left empty (a naive restart would otherwise create a fresh db).
renameSync(file, `${file}.old`);
try {
rmSync(`${file}-wal`, { force: true });
rmSync(`${file}-shm`, { force: true });
renameSync(tmp, file);
} catch (err) {
try {
renameSync(`${file}.old`, file);
} catch {
throw new Error(View on GitHub (pinned to 75dd419e61)
Solutions
- Re-run /prune vacuum with no other sessions able to start: stop dev servers, file watchers, and auto-restart policies
- Repeat the vacuum — the aborted run cleaned up its temp file, no data was lost
- Vacuum during a quiet window (e.g. before starting the TUI, in CI, or maintenance downtime)
Defensive patterns
Strategy: retry
Validate before calling
import { readFileSync } from 'node:fs';
// Re-check just before starting the vacuum that nothing else has the db open
const inWalMode = readFileSync(dbFile).subarray(18, 19).toString() === String.fromCharCode(2);
if (inWalMode) throw new Error('Aborting: db opened in WAL mode by another process.'); Try / catch
try {
await maintenance.results();
} catch (e) {
if (String(e.message).includes('was opened by another process during compaction')) {
console.error('No data lost. Ensure no sessions can start (disable watchers/auto-restart), then re-run the vacuum.');
} else throw e;
} Prevention
- Stop file watchers and auto-restart policies (nodemon, docker restart) before vacuuming multi-GB databases
- Vacuum during maintenance windows or in CI where no other sessions can start
- Keep databases small via regular pruning so the VACUUM window stays short
When it happens
Trigger: A Mastra Code session (or any libsql client) starts and opens the storage db in WAL mode while a long-running /prune vacuum is compacting it; the re-probe just before the rename detects the header flip.
Common situations: A teammate or a watcher (dev server, background agent) starts the app while you vacuum a multi-GB database; an auto-restart (nodemon, docker restart policy) respawns a session mid-vacuum.
Related errors
- ${file} is in use by another process — is another Mastra Cod
- Not enough free disk space to compact ${file}: need ${format
- WORKFLOW_RESUME_ALREADY_CLAIMED
- error.message (workflow resume already claimed conflict)
- MastraFactory.prepare() called twice
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4dda85f634bd518f.
Report an issue: GitHub.