Skip to content

Fix cross-session SQLite transaction collisions during bootstrap/restart #260

@100yenadmin

Description

@100yenadmin

Summary

Lossless-Claw can hit Error: cannot start a transaction within a transaction during restart/bootstrap pressure because multiple sessions share one SQLite DatabaseSync connection, while transaction serialization is only per session and some transaction scopes span awaited async work.

Proven / strongly supported observations

  • One LcmContextEngine instance shares a single DatabaseSync handle across stores/sessions.
  • withSessionQueue() serializes only by sessionKey || sessionId, not globally by DB handle.
  • bootstrap() wraps work in conversationStore.withTransaction(async () => { ... }).
  • withTransaction() issues BEGIN IMMEDIATE, then awaits the operation.
  • Bootstrap performs awaited async work inside that transaction, including session-file reads.
  • Under restart, multiple sessions re-bootstrap in the same runtime window.
  • We observed a real runtime error: context engine bootstrap failed: Error: cannot start a transaction within a transaction.

Why this is unsafe

If session A begins a transaction on the shared DB and then yields on async work, session B (different queue key) can still enter its own transaction path on the same DB connection. SQLite then throws:

cannot start a transaction within a transaction

This appears most likely during restart/bootstrap storms, but the design issue is broader than bootstrap alone: any cross-session DB-mutating operation using the shared connection can collide if transaction scope crosses await.

Candidate fix directions

  1. Do not hold SQLite transactions across async file/network/stream work.
  2. Move bootstrap read/parse planning outside the transaction; keep only the short write/apply section transactional.
  3. Add a process-global DB transaction/write mutex (not only per-session queueing).
  4. Add regression coverage for concurrent multi-session bootstrap / DB-mutating operations.

Reproduction shape

  • shared engine / shared DB handle
  • multiple sessions wake after restart
  • one session enters bootstrap transaction and yields during file read
  • another session enters a transaction path on the same DB
  • nested transaction error is thrown

Notes

A clean v0.6.0 package appears to match the currently synced local source for the relevant bootstrap/transaction files, so this does not look like a packaging-only issue.

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