Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

BLite.Wasm: two tabs on one database lose a committed write (IndexedDB) or cannot open it (OPFS)

Open
#291 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
javascript, wasm
Domain
databases

Research direction

Start with IndexedDbPageStorage.OpenAsync, OpfsPageStorage.OpenAsync, and the locking/worker handling in src/BLite.Wasm/wwwroot/*.mjs, then run the named Two_tabs browser tests. Confirm the implementation consistently prevents concurrent writers and reports a BLite-level error when another tab owns the database, including the OPFS access-handle failure. Update WASM_SUPPORT.md to describe the supported two-tab behavior; broader reader/writer coordination is a separate design effort.

Written by the indexing model from the issue text.

Description

area/multi-process bug package/core severity/high

Two tabs of the same origin open the same database. On IndexedDB, both tabs' writes are acknowledged and checkpointed, and a fresh third tab sees only the second tab's: the first tab's committed write is gone, with no error anywhere. On OPFS the second tab cannot open the database at all. Nothing in BLite.Wasm coordinates tabs, and nothing tells the user that a second tab is unsupported.

Two tabs are two processes on one database, the case the README's multi-process mode covers on desktop ("N-reader / 1-writer access across OS processes", opt-in, with the .wal-shm sidecar). In the browser there is no opt-in, no lock, and no error.

Found by the browser harness (tests/BLite.Wasm.BrowserTests, https://github.com/EntglDb/BLite/pull/295), which carries the affected rows as known candidate BW5 until this is fixed.

Repro

Rows Two_tabs_writing_the_same_database_keep_both_writes IndexedDb and Opfs.

tab A: engine = await BLiteWasm.CreateAsync("shared", IndexedDb)
tab B: engine = await BLiteWasm.CreateAsync("shared", IndexedDb)
tab A: InsertAsync(name="a"); CheckpointAsync()        -> ok
tab B: InsertAsync(name="b"); CheckpointAsync()        -> ok
tab B: FindAllAsync                                    -> b
tab C: await BLiteWasm.CreateAsync("shared", IndexedDb); FindAllAsync   -> b
dotnet test tests/BLite.Wasm.BrowserTests --filter "FullyQualifiedName~Two_tabs"

OPFS: the second CreateAsync throws

JSException: Failed to execute 'createSyncAccessHandle' on 'FileSystemFileHandle': Access Handles cannot be created if there is another open Access Handle or Writable stream associated with the same file.

Expected: a third tab sees a,b; or the second tab gets a clear error on open (as desktop does without AllowMultiProcessAccess), on both backends.

Actual: IndexedDB, a silent lost update; OPFS, an unhandled JSException from the Worker.

Mechanism (verified on 0450b97)

  • Each tab's page store loads every page into its own managed cache on open (IndexedDbPageStorage.OpenAsync, OpfsPageStorage.OpenAsync) and writes the dirty ones back in FlushAsync. Tab B opened before A's write, so its cache has no page of A's; B's allocation hands out the same page ids, and B's checkpoint writes them over A's. The next page id is a single stored value (idbSaveNextPageId) that each tab overwrites with its own.
  • The JS modules take no lock and publish no change: no navigator.locks, BroadcastChannel or onversionchange handling in src/BLite.Wasm/wwwroot/*.mjs, so neither tab learns of the other.
  • On OPFS the browser itself refuses a second createSyncAccessHandle on the file; the error is surfaced raw from the Worker, nothing in OpfsPageStorage.OpenAsync turns it into a BLite error or falls back.

Affected versions: BLite.Wasm since #63 (830e83e, v4.4.0) through v5.2.3.

Fix considerations

  • The cheapest safe behaviour: one writer per origin. Take a navigator.locks lock on the database name in OpenAsync (exclusive, ifAvailable), fail the second open with a BLite exception that says another tab holds the database, and catch the OPFS access-handle error the same way. Then a second tab is a clear error, not a lost update.
  • A reader/writer scheme (one tab writes, others read through a shared WAL) is the multi-process mode's design; in the browser the WAL could be the IndexedDB store with a BroadcastChannel for the generation, as .wal-shm is on desktop. That is a larger piece and a design choice for the maintainers.
  • Either way WASM_SUPPORT.md should state what happens with two tabs.

Related: #110 (the .wal-shm sidecar, the desktop answer to the same problem), #197 / #198 / #200 / #203 / #216 (lost commits between processes, fixed on desktop), #188, #220, #226 (multi-process, open), #57 / #63 (BLite.Wasm). The other issues from the same harness: #289, #290, #292, #293.

Dominant language
C#
Stars
66
Forks
6
Avg merge
1d 2h
Merged PRs (30d)
58

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from EntglDb/BLite

All issues in EntglDb/BLite

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.