Fix: Await table creation in ExpoSQLiteKVStore to prevent race condition #400
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes a race condition in
ExpoSQLiteKVStorewhere theCREATE TABLEstatement is not awaited before preparing subsequent SQL statements. This causes intermittent "no such table: data" errors on fresh app installs in React Native/Expo applications.Problem
In
packages/db/src/kv-store/storage/expo-sqlite.ts, the table creation statement is executed withoutawait:Because
executeAsync()returns a Promise that is not awaited, the subsequentdb.prepareAsync(STATEMENTS.get)calls may execute before thedatatable has been created. This results in the following errors:Or alternatively:
Both errors stem from the same root cause: the table creation has not completed before subsequent statements attempt to reference it.
Reproduction
@triplit/clientwithExpoSQLiteKVStoreEnvironment
@triplit/client: ^1.0.50@triplit/db: 1.1.10expo-sqlite: ~16.0.9Solution
Add
awaitto ensure the table creation completes before preparing other statements:Changes
packages/db/src/kv-store/storage/expo-sqlite.tsawaitbeforecreateTableStatement.executeAsync()Testing
After applying this fix:
Additional Context
The synchronous SQLite implementation (
SQLiteKVStoreinsqlite.ts) does not have this issue because it uses synchronousrun()calls. This bug is specific to the async Expo SQLite implementation where Promise-based operations require explicit awaiting.