#3811·nanoclaw

Central DB has no busy_timeout, so lock contention throws as if it were corruption

Author: DawoudIOCreated Sep 14, 2026Updated Sep 14, 2026

Summary

The central DB (src/db/compose.ts) — task/schedule state, container_configs, agent_groups — is opened in WAL mode with no busy_timeout set. Any momentary lock contention (two processes touching it at once) throws immediately instead of waiting briefly and retrying, which is indistinguishable from real corruption to a caller seeing ncl tasks list / ncl tasks run fail.

The session DBs (inbound.db/outbound.db) already carry this protection — see container/agent-runner/src/cli/ncl.ts's busy_timeout=5000 on both connections. The central DB never did.

Fix

typescript
// src/db/compose.ts
if (!options.readonly) raw.pragma('busy_timeout = 5000');

Same value already used for the session DBs, so behavior stays consistent across all three.

Scope note

This does not fix an ungraceful-shutdown-mid-write scenario (the other candidate cause of intermittent task-DB failures on a real install) — only the contention half. Not the same issue as #3708 (closed, unmerged) or #2640/#2750/#2196/#2188, which are all about outbound.db's readonly/journal handling — this is the central DB specifically, a different file with no existing coverage.

PR follows.