jackwener/OpenCLI · error · CommandExecutionError

sqlite3 failed on ${path.basename(db)}: ${e.message}

Error message

sqlite3 failed on ${path.basename(db)}: ${e.message}

What it means

sqliteQuery executes /usr/bin/sqlite3 via execFileSync; any failure (non-zero exit, missing binary, spawn error) is wrapped in a CommandExecutionError that includes the sqlite3 stderr/message. The most common cause is the database being locked by the running Antigravity instance, as the hint says.

Source

Thrown at clis/antigravity/storage.js:49

    'Field',
    'Value',
];

// ====== Path helpers ======
const AG_APP_SUPPORT = path.join(os.homedir(), 'Library/Application Support/Antigravity');
const AG_USER_DIR = path.join(AG_APP_SUPPORT, 'User');
const AG_GLOBAL_STATE_DB = path.join(AG_USER_DIR, 'globalStorage/state.vscdb');
const AG_WORKSPACE_STORAGE = path.join(AG_USER_DIR, 'workspaceStorage');
const AG_SETTINGS_JSON = path.join(AG_USER_DIR, 'settings.json');

function sqliteQuery(db, sql) {
    if (!fs.existsSync(db)) {
        throw new CommandExecutionError(`state.vscdb not found: ${db}`, 'Has Antigravity been run at least once?');
    }
    try {
        return execFileSync('/usr/bin/sqlite3', [db, sql], { encoding: 'utf-8', maxBuffer: 64 * 1024 * 1024 });
    } catch (e) {
        throw new CommandExecutionError(
            `sqlite3 failed on ${path.basename(db)}: ${e.message}`,
            'The DB may be locked by a running Antigravity instance. Try closing it or wait a few seconds.',
        );
    }
}
function listKeys(db) {
    const out = sqliteQuery(db, 'SELECT key FROM ItemTable ORDER BY key;');
    return out.split('\n').map((s) => s.trim()).filter(Boolean);
}
function getValue(db, key) {
    const esc = key.replace(/'/g, "''");
    const raw = sqliteQuery(db, `SELECT value FROM ItemTable WHERE key = '${esc}';`).trim();
    if (!raw) return null;
    try { return JSON.parse(raw); } catch { return raw; }
}
function resolveStateDb(args) {
    const ws = args?.workspace ? String(args.workspace).trim() : '';
    if (!ws) return AG_GLOBAL_STATE_DB;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Close Antigravity (or wait a few seconds) so the DB lock is released, then retry
  2. Copy the db (+ -wal/-shm files) and query the copy to avoid the lock
  3. Install sqlite3 or fix the hardcoded /usr/bin/sqlite3 path (which sqlite3)
  4. Open the DB with 'sqlite3 db "PRAGMA integrity_check;"' to rule out corruption
  5. Fix the SQL statement if using the raw command and the message is a syntax error

Example fix

// before
sqliteQuery(db, sql) // while Antigravity is running -> SQLITE_BUSY
// after
cp state.vscdb /tmp/state-copy.vscdb && cp state.vscdb-wal /tmp/state-copy.vscdb-wal
sqliteQuery('/tmp/state-copy.vscdb', sql)
Defensive patterns

Strategy: retry

Validate before calling

const { execFileSync } = require('child_process');
const sqlite3Path = ['/usr/bin/sqlite3', '/usr/local/bin/sqlite3'].find(p => fs.existsSync(p));
if (!sqlite3Path) throw new Error('sqlite3 is not installed');

Try / catch

async function queryWithRetry(db, sql, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try { return sqliteQuery(db, sql); }
    catch (err) {
      if (!/sqlite3 failed/.test(err.message) || i === attempts - 1) throw err;
      await new Promise(r => setTimeout(r, 2000 * (i + 1))); // wait out DB lock
    }
  }
}

Prevention

When it happens

Trigger: execFileSync('/usr/bin/sqlite3', [db, sql]) throws: DB locked (SQLITE_BUSY), corrupt DB, sqlite3 binary not installed at /usr/bin/sqlite3, or the SQL is invalid.

Common situations: Antigravity is open and holds a write lock on state.vscdb (WAL/journal contention); sqlite3 not installed or installed at a non-standard path (e.g. /usr/local/bin, macOS Homebrew /opt/homebrew); malformed custom SQL passed to raw; corrupted profile after a crash.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/b67bc82fe3fa5754. Report an issue: GitHub.