mastra-ai/mastra · error

${file} is in use by another process — is another Mastra Cod

Error message

${file} is in use by another process — is another Mastra Code session running? Close other sessions and run /prune vacuum again.

What it means

reclaimLibSQLDisk compacts a SQLite/libsql database file by VACUUMing it into a copy. Before compaction it probes the file's journal-mode header; a healthy single-process database must read 'delete'. If the header says otherwise (e.g. 'wal'), another process has the database open, and vacuuming/compacting under it would corrupt or orphan data, so the operation is refused.

Source

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

    // does not finalize outstanding statements — they are only finalized by
    // GC, so lock release after close() is nondeterministic. Reported as
    // https://github.com/tursodatabase/libsql-js/issues/228 (fix in flight in
    // PR #214). Once that lands, the header check can become a plain
    // journal_mode query.
    const probe = new Database(file);
    try {
      probe.exec('PRAGMA busy_timeout = 2000');
      // Round-trip through WAL so the probe also works when a clean shutdown
      // already left the file in rollback mode.
      probe.exec('PRAGMA journal_mode = WAL');
      probe.exec('PRAGMA journal_mode = DELETE');
    } catch {
      // busy — the header check below reports the failure
    } finally {
      probe.close();
    }
    if (journalModeFromHeader(file) !== 'delete') {
      throw new Error(
        `${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)) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Close every other Mastra Code session and any process with the file open (check with `lsof <file>`), then run /prune vacuum again
  2. Remove stale sidecars only after confirming no process holds the db: delete `<file>-wal` and `<file>-shm`
  3. Retry the vacuum in a single dedicated terminal while no dev server is running
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync } from 'node:fs';
const header = readFileSync(dbFile).subarray(18, 19).toString(); // journal-mode byte: 1=delete(rollback), 2=wal
if (header === String.fromCharCode(2)) {
  throw new Error('Database is in WAL mode — another process likely has it open. Close sessions before vacuum.');
}

Type guard

const isRollbackMode = (file: string): boolean =>
  readFileSync(file).subarray(18, 19).toString() === String.fromCharCode(1);

Try / catch

try {
  await maintenance.results();
} catch (e) {
  if (String(e.message).includes('is in use by another process')) {
    console.error('Close other Mastra sessions (check `lsof <db>`) and re-run the vacuum.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running /prune vacuum (createStorageMaintenance → reclaimLibSQLDisk) while another Mastra Code session, dev server, or any SQLite/libsql client has the same storage file open in WAL mode; or a crashed session left stale -wal/-shm sidecars and a lingering open handle.

Common situations: Two mastracode TUI sessions sharing one project storage file; a `mastra dev` server left running in another terminal; an IDE SQLite extension holding the db; a previous vacuum crashed leaving WAL sidecars.

Related errors


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