Skip to content

Conversation

@lizterangelo
Copy link

Summary

This PR fixes a race condition in ExpoSQLiteKVStore where the CREATE TABLE statement 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 without await:

const createTableStatement = await db.prepareAsync(STATEMENTS.createTable);
createTableStatement.executeAsync(); // ← Not awaited!
return {
    db,
    statements: {
        createTable: createTableStatement,
        get: await db.prepareAsync(STATEMENTS.get), // ← May fail if table doesn't exist yet
        // ... other prepared statements
    },
};

Because executeAsync() returns a Promise that is not awaited, the subsequent db.prepareAsync(STATEMENTS.get) calls may execute before the data table has been created. This results in the following errors:

TriplitError: Failed to create a DB instance: Calling the 'prepareAsync' function has failed
→ Caused by: Error code 1: no such table: data

Or alternatively:

TriplitError: Failed to create a DB instance: Calling the 'prepareAsync' function has failed
→ Caused by: Error code 0: no more rows available

Both errors stem from the same root cause: the table creation has not completed before subsequent statements attempt to reference it.

Reproduction

  1. Fresh install of an Expo app using @triplit/client with ExpoSQLiteKVStore
  2. Launch the app for the first time
  3. The error occurs intermittently (race condition timing-dependent)
  4. Restarting the app resolves the issue because the table now exists from the previous attempt

Environment

  • @triplit/client: ^1.0.50
  • @triplit/db: 1.1.10
  • expo-sqlite: ~16.0.9
  • Platform: iOS/Android (React Native with Expo)

Solution

Add await to ensure the table creation completes before preparing other statements:

const createTableStatement = await db.prepareAsync(STATEMENTS.createTable);
await createTableStatement.executeAsync(); // ← Now properly awaited
return {
    db,
    statements: {
        // ... statements are now safe to prepare
    },
};

Changes

  • File: packages/db/src/kv-store/storage/expo-sqlite.ts
  • Change: Add await before createTableStatement.executeAsync()

Testing

After applying this fix:

  • Fresh installs no longer produce the "no such table: data" error
  • Existing functionality remains unchanged
  • No performance impact (table creation is a one-time operation)

Additional Context

The synchronous SQLite implementation (SQLiteKVStore in sqlite.ts) does not have this issue because it uses synchronous run() calls. This bug is specific to the async Expo SQLite implementation where Promise-based operations require explicit awaiting.

Added missing await to ensure the table creation statement completes before proceeding in the ExpoSQLiteKVStore initialization.
@vercel
Copy link

vercel bot commented Dec 19, 2025

@lizterangelo is attempting to deploy a commit to the Aspen Cloud Team on Vercel.

A member of the Team first needs to authorize it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant