Summary
When using routstrd with @routstr/sdk under Bun, SDK state persistence can log intermittent SQLite errors during provider/model discovery:
SQLite setItem failed for key "lastModelsUpdate"
SQLiteError: database is locked
code: "SQLITE_BUSY"
This appears during bootstrap / refresh, while the daemon may otherwise continue working normally (e.g. models still get discovered and downstream integrations may still update successfully).
Environment
routstrd
@routstr/sdk
- Bun SQLite (
bun:sqlite)
- Shared SQLite DB path used for SDK state, and possibly other persistence concerns in the daemon
Observed behavior
During ModelManager.fetchModels(...), provider fetches run in parallel and the SDK persists discovery state repeatedly, including updates to:
lastModelsUpdate
- provider last-update timestamps
- cached model data
Under Bun SQLite, some of those writes fail with SQLITE_BUSY / database is locked.
Likely cause
A combination of:
- concurrent writes triggered by parallel provider discovery in
fetchModels()
- multiple writes to the same persisted SDK state keys in quick succession
- possibly multiple DB handles/subsystems sharing the same SQLite file in the app
- Bun SQLite driver in SDK not appearing to use WAL, busy timeout, or serialized write handling
Impact
- persistence of discovery/cache metadata can fail intermittently
- may lead to stale or missing timestamps/cache writes
- can cause unnecessary refetches or flaky discovery persistence
- often non-fatal, but noisy and potentially unreliable over time
Relevant code paths
App side:
src/daemon/models.ts
src/daemon/index.ts
SDK side:
createBunSqliteDriver(...)
createSdkStore(...)
createDiscoveryAdapterFromStore(...)
ModelManager.fetchModels(...)
Suggested fix
Long-term fix should be in @routstr/sdk storage/concurrency handling for Bun:
- enable SQLite WAL mode
- set a busy timeout
- serialize or batch writes to persisted SDK state
- reduce write frequency during parallel provider discovery where possible
Workarounds
App-level mitigations that may reduce frequency:
- use separate SQLite DB files for SDK state vs usage tracking/other subsystems
- add a single-flight guard so only one model refresh runs at a time
Notes
This seems to be primarily an SDK storage/concurrency issue rather than a provider/discovery correctness issue. In observed cases, model discovery still largely completed despite the logged errors.
Summary
When using
routstrdwith@routstr/sdkunder Bun, SDK state persistence can log intermittent SQLite errors during provider/model discovery:This appears during bootstrap / refresh, while the daemon may otherwise continue working normally (e.g. models still get discovered and downstream integrations may still update successfully).
Environment
routstrd@routstr/sdkbun:sqlite)Observed behavior
During
ModelManager.fetchModels(...), provider fetches run in parallel and the SDK persists discovery state repeatedly, including updates to:lastModelsUpdateUnder Bun SQLite, some of those writes fail with
SQLITE_BUSY/database is locked.Likely cause
A combination of:
fetchModels()Impact
Relevant code paths
App side:
src/daemon/models.tssrc/daemon/index.tsSDK side:
createBunSqliteDriver(...)createSdkStore(...)createDiscoveryAdapterFromStore(...)ModelManager.fetchModels(...)Suggested fix
Long-term fix should be in
@routstr/sdkstorage/concurrency handling for Bun:Workarounds
App-level mitigations that may reduce frequency:
Notes
This seems to be primarily an SDK storage/concurrency issue rather than a provider/discovery correctness issue. In observed cases, model discovery still largely completed despite the logged errors.