Skip to content

Failed Open on torn free-list leaks FileShare.None handle after Dispose #121

Description

@KarataevDmitry

Context

Consumer: CDP MCP / CascadeIDE intent-workspace seat DB (EF Core OutWit.Database.EntityFramework 1.0.3).

Bug

When Open fails with torn free-list / ArgumentOutOfRangeException: Page number … out of range (FreePage ≥ TotalPageCount after kill/remount pressure), the process often keeps an exclusive FileShare.None handle after the failed open/Dispose.

Subsequent opens then fail with IOException: … being used by another process within ~50ms (no real contention), and quarantine/File.Move of the torn file also fails until the process is killed.

Expected

Failed Open must not leave a sticky exclusive OS handle. Dispose/failed Open path should release the file so callers can quarantine or reopen.

Repro sketch

  1. Produce a large seat *.witdb with torn free-list (dual-seat/FileShare fights or abrupt Kill mid-write historically did this).
  2. new DbContext(...UseWitDb...).Database open / EnsureCreated → pageNumber OOR.
  3. Immediately retry Open or File.Move of the same path → being used by another process while no other process holds the file.
  4. GC + sleep sometimes insufficient; process Kill clears the leak.

Impact

Forced us to leave WitDB for seat storage (migrating to SQLite). Filing so the engine can fix handle lifetime on failed Open.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions