jackwener/OpenCLI · warning · CommandExecutionError
Trae is actively writing (database.db-wal touched ${(ageMs /
Error message
Trae is actively writing (database.db-wal touched ${(ageMs / 1000).toFixed(1)}s ago). What it means
checkAgentDbQuiet is a concurrency guard: before mutating Trae SOLO's ai-agent SQLite state, it checks the modification time of database.db-wal (SQLite write-ahead log). If the WAL was touched within windowSec (default 5s), Trae is assumed to be actively writing and the library refuses to mutate the DB to avoid corruption or lost writes.
Source
Thrown at clis/trae-solo/_fs.js:113
}
// Atomically update skill-config.json — read, mutate via callback, write
// via tmp + rename to avoid Trae seeing a half-written file.
export function updateSkillConfig(mutate) {
const conf = readSkillConfig();
mutate(conf);
const tmp = TRAE_SKILL_CONFIG + '.tmp-' + process.pid;
fs.writeFileSync(tmp, JSON.stringify(conf, null, 4));
fs.renameSync(tmp, TRAE_SKILL_CONFIG);
}
// Refuse to mutate ai-agent on-disk state if database.db-wal was touched
// in the last `windowSec` seconds — Trae is probably writing.
export function checkAgentDbQuiet(windowSec = 5) {
if (!fs.existsSync(TRAE_DB_WAL)) return; // first run
const ageMs = Date.now() - fs.statSync(TRAE_DB_WAL).mtimeMs;
if (ageMs < windowSec * 1000) {
throw new CommandExecutionError(
`Trae is actively writing (database.db-wal touched ${(ageMs / 1000).toFixed(1)}s ago).`,
`Wait ${windowSec}+ s for Trae to settle, or quit Trae SOLO before mutating state.`,
);
}
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Close or quit the Trae SOLO application before running the mutating command
- Wait at least windowSec (5s, or pass a larger windowSec) and retry
- Retry in a loop with backoff until the WAL is quiet
- Temporarily stop background Trae agents/sync that keep writing to the DB
Example fix
// before
await traeSoloCli.config.set(k, v); // throws: actively writing
// after
async function runQuiet(fn, tries = 10) {
for (let i = 0; i < tries; i++) {
try { return await fn(); }
catch (e) {
if (!/actively writing/.test(e.message)) throw e;
await new Promise(r => setTimeout(r, 3000));
}
}
throw new Error('Trae DB never quiet');
}
runQuiet(() => traeSoloCli.config.set(k, v)); Defensive patterns
Strategy: retry
Validate before calling
import fs from 'fs';
const wal = TRAE_DB_WAL;
if (fs.existsSync(wal)) {
const age = Date.now() - fs.statSync(wal).mtimeMs;
if (age < 5000) throw new Error(`Trae DB busy (touched ${age}ms ago); wait and retry.`);
} Try / catch
try {
await mutateCmd();
} catch (e) {
if (/actively writing/.test(e.message)) {
await new Promise(r => setTimeout(r, 6000));
return mutateCmd(); // single retry after settling
}
throw e;
} Prevention
- Quit Trae SOLO before running any state-mutating commands
- Serialize automation scripts; avoid concurrent CLI writers
- Pass a larger windowSec when Trae syncs frequently
- Check WAL mtime yourself in a pre-flight step
When it happens
Trigger: Calling a state-mutating command while the Trae SOLO app is running and has written to database.db-wal less than windowSec seconds ago.
Common situations: Automating Trae SOLO while the desktop app is left open and syncing; running several CLI invocations back-to-back so the WAL keeps being touched; a background Trae process (indexing/sync) writing continuously.
Related errors
- sqlite3 failed on ${path.basename(db)}: ${e.message}
- sqlite3 failed on ${path.basename(db)}: ${e.message}
- state.vscdb not found: ${db}
- state.vscdb not found: ${db}
- antigravity state-keys: No keys match "${flt}".
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0e05dd5f198c566a.
Report an issue: GitHub.