mastra-ai/mastra · error

Not enough free disk space to compact ${file}: need ${format

Error message

Not enough free disk space to compact ${file}: need ${formatBytes(requiredFreeBytes(liveBytes))} for a ${formatBytes(liveBytes)} compacted copy, but only ${formatBytes(freeBytes)} is free.

What it means

Before compacting, reclaimLibSQLDisk computes the live (non-freelist) bytes of the database and requires free disk space sufficient to hold a full compacted copy (VACUUM INTO writes a copy next to the file). If the filesystem's free space (statfsSync) is below that requirement, it aborts instead of risking a failed mid-write compaction.

Source

Thrown at mastracode/sdk/src/utils/storage-maintenance.ts:197

        `${file} is in use by another process — is another Mastra Code session running? ` +
          `Close other sessions and run /prune vacuum again.`,
      );
    }
    // Native `libsql` driver, not `@libsql/client`: the wrapper's close() can
    // leave the file lock held in-process (cached statements), which would
    // block other connections afterwards. This connection stays in rollback
    // mode, so even a pinned statement holds no lock once we're done.
    const db = new Database(file);
    try {
      db.exec('PRAGMA busy_timeout = 2000');
      const pageSize = pragmaNumber(db, 'page_size');
      const pageCount = pragmaNumber(db, 'page_count');
      const freelistCount = pragmaNumber(db, 'freelist_count');
      const liveBytes = Math.max(0, pageCount - freelistCount) * pageSize;
      const { bsize, bavail } = statfsSync(dirname(file));
      const freeBytes = bsize * bavail;
      if (freeBytes < requiredFreeBytes(liveBytes)) {
        throw new Error(
          `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 });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Free disk space on the volume (delete build artifacts, logs, `docker system prune`) so at least requiredFreeBytes(liveBytes) is available
  2. Move or prune large thread data first (smaller liveBytes reduces the needed space)
  3. Run the vacuum on a machine/volume with sufficient free space, e.g. copy the project to a bigger disk
Defensive patterns

Strategy: validation

Validate before calling

import { statfsSync, statSync } from 'node:fs';
const { bsize, bavail } = statfsSync(dirname(dbFile));
const freeBytes = bsize * bavail;
const liveBytes = statSync(dbFile).size; // rough upper bound of the compacted copy
if (freeBytes < liveBytes * 1.2) throw new Error(`Need ~${liveBytes * 1.2} bytes free to compact; only ${freeBytes} free.`);

Try / catch

try {
  await maintenance.results();
} catch (e) {
  if (String(e.message).includes('Not enough free disk space')) {
    console.error('Free up space or run the vacuum on a larger volume, then retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running /prune vacuum on a storage file whose live bytes exceed the free space on the volume — e.g. a multi-GB db on a nearly full disk, or a small container volume / CI runner with tight disk quota.

Common situations: Docker volumes or CI machines with a few GB of free space hosting large thread/memory databases; log files or build artifacts filling the disk before a vacuum.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/bb63542c07f9f078. Report an issue: GitHub.