github mksglu/context-mode v1.0.143

latest release: v1.0.144
3 hours ago

v1.0.143

Single critical fix: every Node ≥22.5 install (everyone on v1.0.132 or later) was running with busy_timeout = 0 on the SessionDB and ContentStore. Multi-writer SQLite operations failed instantly with Error: database is locked instead of waiting up to 30s like ADR-0001 promises.

Fix

node:sqlite adapter now sets busy_timeout (#642). When commit 302bb7b (#228) added the dual loadDatabase() adapter pattern in 2024, the node:sqlite (Node ≥22.5) branch constructed new DatabaseSync(path, { readOnly }) and dropped opts.timeout on the floor. node:sqlite's constructor silently ignores { timeout } — the Bun branch got the matching pragma("busy_timeout = ...") fix two hours later in #243, but the node:sqlite branch was never updated. Two years live.

Symptom: SessionStart hook's unconditional DELETE + ensureSession raced against any concurrent MCP write (multi-window, parallel hooks, lifecycle sweep) and surfaced as instant SQLITE_BUSY instead of waiting 30s. The reporter's withRetry() wrapper around withRetry(() => ...) was 30,000× weaker than the ADR-0001 contract claimed because the underlying pragma was never set.

Fix is one line: adapter.pragma(\busy_timeout = ${opts.timeout}`)afterDatabaseSync` construction on the Node-modern branch. Restores the ADR-0001 multi-writer contract that v1.0.130's lockfile rollback assumed was working. Closes #642.

Tests

3 new tests added to existing tests/util/db-base-platform-gate.test.ts (CONTRIBUTING L275 — no new test files):

  • Runtime invariant — public loadDatabase() factory + pragma("busy_timeout") assertion, driver-agnostic
  • Source-pin invariant — regex-pins NodeDatabaseFactory MUST contain the busy_timeout pragma call (RED→GREEN proven via git stash)
  • node:sqlite direct (host-gated on require('node:sqlite')) — adapter wiring sanity

Mirrors ADR-0001's dual-anchor defense pattern (behavioral + source-pin).

105/105 adjacent DB tests pass. Full suite preserves baseline.

Compatibility

15 adapters, 3 OS. No schema migration. engines.node >= 22.5.0 preserved.

Upgrade

npm install -g context-mode@latest
# Restart Claude Code (Cmd+Q + reopen) — the busy_timeout is set at DB open, so existing in-memory DB handles keep the old (zero) value until restart.

Why this matters

If you ever saw SQLITE_BUSY: database is locked from any context-mode operation since v1.0.132, this is why. Multi-window users especially. The ADR-0001 contract was effectively unenforced on the dominant Node path for two years — v1.0.130's lockfile rollback shipped on top of this undiagnosed regression, making "ADR-0001 multi-writer-safe" technically true but practically defeated.

Credits

  • Reporter who diagnosed #642 — pointed at exactly the right code path (NodeSQLiteAdapter constructor) with the exact mechanism (silently-ignored { timeout } option). Their suggested wrap of hooks/sessionstart.mjs DELETE in db.withRetry() is a sound defense-in-depth follow-up.

Don't miss a new context-mode release

NewReleases is sending notifications on new releases.