{"record":{"id":"0e05dd5f198c566a","repo":"jackwener/OpenCLI","slug":"trae-is-actively-writing-database-db-wal-touched","errorCode":null,"errorMessage":"Trae is actively writing (database.db-wal touched ${(ageMs / 1000).toFixed(1)}s ago).","messagePattern":"Trae is actively writing \\(database\\.db-wal touched (.+?)s ago\\)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"warning","filePath":"clis/trae-solo/_fs.js","lineNumber":113,"sourceCode":"}\n\n// Atomically update skill-config.json — read, mutate via callback, write\n// via tmp + rename to avoid Trae seeing a half-written file.\nexport function updateSkillConfig(mutate) {\n    const conf = readSkillConfig();\n    mutate(conf);\n    const tmp = TRAE_SKILL_CONFIG + '.tmp-' + process.pid;\n    fs.writeFileSync(tmp, JSON.stringify(conf, null, 4));\n    fs.renameSync(tmp, TRAE_SKILL_CONFIG);\n}\n\n// Refuse to mutate ai-agent on-disk state if database.db-wal was touched\n// in the last `windowSec` seconds — Trae is probably writing.\nexport function checkAgentDbQuiet(windowSec = 5) {\n    if (!fs.existsSync(TRAE_DB_WAL)) return; // first run\n    const ageMs = Date.now() - fs.statSync(TRAE_DB_WAL).mtimeMs;\n    if (ageMs < windowSec * 1000) {\n        throw new CommandExecutionError(\n            `Trae is actively writing (database.db-wal touched ${(ageMs / 1000).toFixed(1)}s ago).`,\n            `Wait ${windowSec}+ s for Trae to settle, or quit Trae SOLO before mutating state.`,\n        );\n    }\n}\n","sourceCodeStart":95,"sourceCodeEnd":119,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trae-solo/_fs.js#L95-L119","documentation":"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.","triggerScenarios":"Calling a state-mutating command while the Trae SOLO app is running and has written to database.db-wal less than windowSec seconds ago.","commonSituations":"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.","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"],"exampleFix":"// before\nawait traeSoloCli.config.set(k, v); // throws: actively writing\n// after\nasync function runQuiet(fn, tries = 10) {\n  for (let i = 0; i < tries; i++) {\n    try { return await fn(); }\n    catch (e) {\n      if (!/actively writing/.test(e.message)) throw e;\n      await new Promise(r => setTimeout(r, 3000));\n    }\n  }\n  throw new Error('Trae DB never quiet');\n}\nrunQuiet(() => traeSoloCli.config.set(k, v));","handlingStrategy":"retry","validationCode":"import fs from 'fs';\nconst wal = TRAE_DB_WAL;\nif (fs.existsSync(wal)) {\n  const age = Date.now() - fs.statSync(wal).mtimeMs;\n  if (age < 5000) throw new Error(`Trae DB busy (touched ${age}ms ago); wait and retry.`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await mutateCmd();\n} catch (e) {\n  if (/actively writing/.test(e.message)) {\n    await new Promise(r => setTimeout(r, 6000));\n    return mutateCmd(); // single retry after settling\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["sqlite","concurrency","locked-database","trae-solo"],"backgroundTag":"database-locked","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}