Skip to content

copy_session_events() lacks BEGIN IMMEDIATE lock; concurrent copy operations produce duplicate seq values #119

Open

Description

@knight22-21

Summary

copy_session_events() in session/store.py inserts events in a loop inside a with _conn(db_path) as conn: block without acquiring an exclusive lock (no BEGIN IMMEDIATE). The append_event() function was recently fixed (PR #110) to use BEGIN IMMEDIATE to prevent TOCTOU races, but copy_session_events was not updated. If two callers copy events into the same target session concurrently, they can produce duplicate seq values because the manual for i, ev in enumerate(events) indexing assumes exclusive write access.

Steps to Reproduce

  1. Create a session with 5 events.
  2. Call copy_session_events(from_id, to_id) from two threads simultaneously (both targeting the same to_id).
  3. Observe duplicate seq values in the target session's events table.

Root Cause

session/store.py around line 278:

def copy_session_events(from_id, to_id, db_path=None):
    events = get_events(from_id, db_path)
    now = time.time()
    with _conn(db_path) as conn:
        for i, ev in enumerate(events):   # seq = i, no lock
            conn.execute(
                """INSERT INTO events ... VALUES (?, ?, ?, ...)""",
                (to_id, i, ev["role"], ...),
            )
    return len(events)

Unlike append_event (fixed in #110), there is no BEGIN IMMEDIATE to serialize access.

Fix Direction

  • Add conn.execute("BEGIN IMMEDIATE") before the insertion loop and conn.commit() after, matching the pattern in append_event.
  • Add a test that copies events from two threads and asserts all seq values in the target are unique.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions