Skip to content

SQLite database is locked errors during model discovery with Bun / routstrd #195

@sh1ftred

Description

@sh1ftred

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:

  1. concurrent writes triggered by parallel provider discovery in fetchModels()
  2. multiple writes to the same persisted SDK state keys in quick succession
  3. possibly multiple DB handles/subsystems sharing the same SQLite file in the app
  4. 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:

  1. enable SQLite WAL mode
  2. set a busy timeout
  3. serialize or batch writes to persisted SDK state
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions