F2: never reindex on a transient sqlite lock

↗ view on GitHub · Eli Ziff · 2026-07-31 · 1ca6a238

`ensurePassageIndex`'s meta probe was wrapped in `catch {}`, so a
SQLITE_BUSY raised by a concurrent reader fell through to
DROP TABLE + full reindex of a HEALTHY sidecar. Observed live twice on
2026-07-31; on the 5.5 GB CourtListener corpus it is hours of work
destroyed by a race.

Verified shape (node 22.20, node:sqlite): the read-only OPEN succeeds and
the `SELECT ... FROM meta` throws `Error { code: "ERR_SQLITE_ERROR",
errcode: 5, errstr: "database is locked" }` - i.e. the failure lands
exactly in the swallowed catch, not at open.

`isSqliteLockError` classifies on the primary result code (low byte of
the extended `errcode`): SQLITE_BUSY 5 and SQLITE_LOCKED 6, so 261/517/773
classify as transient too; message fallback for errors that lost the
numeric field. Transient -> rethrow (caller retries); corrupt/foreign ->
rebuild, unchanged.

Tests (backend/src/lib/__tests__/passageRetrieval.test.ts): a real
exclusive lock produces a real errcode-5 error and is classified
transient; under that lock `ensurePassageIndex` rethrows "database is
locked" and the sidecar survives (built:false, identical counts
afterwards); a foreign-but-readable sidecar still rebuilds. The
integration test discriminates the two code paths by pointing sourceDb at
a missing file - the rebuild path opens the source FIRST, so pre-fix it
reports "unable to open database file". Mutation-checked: reverting the
rethrow fails 2 of the 3 tests.

No scoring, chunking or retrieval semantics touched; no measured number
moves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9ToHYJVDxfeJcJwdzrP2H
Repository eliziff/Beaver
Author Eli Ziff <eliasziff@gmail.com>
Authored
Parents e15d2d0d
Stats 2 files changed , +157 , -3
Part of Legal agent-surface and context-compaction experiments

Capture this commit into my fork

Download a Markdown prompt that tells Claude how to port this exact commit into your working tree. Run it via claude -p < capture-commit-1ca6a238.md from inside the repo you want the change in.

⬇ Download capture-commit-1ca6a238.md