Skip to content

fix(init): bound the first database query so boot cannot hang forever - #1199

Open
njbrake wants to merge 3 commits into
thunderbird:mainfrom
njbrake:pr1-bound-initial-db-query
Open

fix(init): bound the first database query so boot cannot hang forever#1199
njbrake wants to merge 3 commits into
thunderbird:mainfrom
njbrake:pr1-bound-initial-db-query

Conversation

@njbrake

@njbrake njbrake commented Aug 6, 2026

Copy link
Copy Markdown

Hi fellow mozillians! I work on https://github.com/mozilla-ai/[otari](https://github.com/mozilla-ai/otari), the mozilla.ai LLM gateway, and as a part of foxfooding I ran thunderbolt (in Railway). I have a few contributions, depending on interest. I'll start with this one and let me know if you would like more, or if you want me to pause.

You can see some of the other PRs I have staged by looking at my fork https://github.com/njbrake/thunderbolt/pulls or the github issues I created in my fork https://github.com/njbrake/thunderbolt/issues. I didn't want to spam you with PRs and Issues unless you want them :)

Now, here's Claude 😄 ->

Note: this PR description was drafted by Claude via back-and-forth with @njbrake. The reasoning and decisions are his; the prose is Claude's.

Bounds the first database query at boot so a broken local database cannot hang the app forever.

step2b_db_ready awaited db.get(sqlselect 1) with no timeout. That is where PowerSync compiles its WASM and opens storage, so a device whose local database is unusable sits on the loading screen indefinitely with no way out.

Nothing upstream of it catches this: createAppDir returns the string 'app-data' without touching OPFS, and the step0_5 probe only opens IndexedDB.

The query now races a 30s ceiling and reports DATABASE_INIT_FAILED, which surfaces the existing error screen along with its clear-database button. That button is the remedy users actually need, and clearing site data is not equivalent because OPFS survives it.

4 new tests drive the timeout, the failure, and the success paths through the suite's fake clock.

_Note: this PR description was drafted by Claude via back-and-forth with @njbrake. The reasoning and decisions are his; the prose is Claude's._

Bounds the first database query at boot so a broken local database cannot hang the app forever.

`step2b_db_ready` awaited `db.get(sql`select 1`)` with no timeout. That is where PowerSync compiles its WASM and opens storage, so a device whose local database is unusable sits on the loading screen indefinitely with no way out.

Nothing upstream of it catches this: `createAppDir` returns the string `'app-data'` without touching OPFS, and the step0_5 probe only opens IndexedDB.

The query now races a 30s ceiling and reports `DATABASE_INIT_FAILED`, which surfaces the existing error screen along with its clear-database button. That button is the remedy users actually need, and clearing site data is not equivalent because OPFS survives it.

4 new tests drive the timeout, the failure, and the success paths through the suite's fake clock.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Preview environment deployed 🚀

Service URL
Marketing / blog / docs https://thunderbolt-pr-1199.preview.thunderbolt.io
App https://app-pr-1199.preview.thunderbolt.io
API https://api-pr-1199.preview.thunderbolt.io
Keycloak https://auth-pr-1199.preview.thunderbolt.io
PowerSync https://powersync-pr-1199.preview.thunderbolt.io

Stack: preview-pr-1199 · Commit: 788f6519ccbd8476b16f28932120ae1e93a31801

Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — demo@thunderbolt.io / demo by default.

@ital0

ital0 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Hey @njbrake thanks for this! The claims check out: the heavy PowerSync work really is deferred to the first query, and today a hang there means an infinite spinner. Bounding it is the right call.

CI is down at the moment (GitHub incident), so I ran things locally: new tests pass, tsc is clean, and the only suite failure also fails on main. I'll kick off the checks once GitHub recovers.

I pushed two small commits on top: one passes the caught error into createHandleError so the support email and PostHog keep the stack trace, and one swaps the hand-rolled timeout race for our existing withTimeout helper.

Keep the PRs coming :)

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.

2 participants