Skip to content

fix(frontend): gate app boot on ConfigStore.hasLoaded to avoid loader deadlock#7776

Open
talissoncosta wants to merge 2 commits into
mainfrom
fix/config-provider-boot-race
Open

fix(frontend): gate app boot on ConfigStore.hasLoaded to avoid loader deadlock#7776
talissoncosta wants to merge 2 commits into
mainfrom
fix/config-provider-boot-race

Conversation

@talissoncosta

Copy link
Copy Markdown
Contributor

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Root cause of the intermittent E2E failures blocking the production deploy gate since Jun 9 (see Slack thread). Replaces #7775 (closed; GitHub blocks reopening after a force-push).

Two stacked problems in the app's boot gate:

  1. ConfigProvider decides whether the app is still loading by checking ConfigStore.model — but model is never populated (flagsmith.getAllFlags() returns nothing at the point config-store.js assigns it; instrumentation showed hasLoaded: true, model: null while the SDK itself held 132 flags). So every mount starts in the loading state regardless of the store's actual state.
  2. The only escape is the store's one-shot change event, which the provider subscribes to in componentDidMount. If the SDK's onChange fires before that subscription (fast edge response + slow runner), the event is lost. In E2E mode realtime, enableEvents and enableAnalytics are all disabled, so no later event ever arrives and the app sits on the boot loader permanently — tests time out waiting for the login form on a page that never booted. Real users are rescued by realtime/analytics-driven events, which is why this only surfaced in E2E.

Fix, one commit each: gate the initial state on hasLoaded (which is reliably set), and re-read the store after subscribing so an event landing in the constructor→subscription gap cannot strand the boot.

How did you test this code?

Deterministic A/B validation by artificially forcing the race (subscription delayed 3s so the SDK's onChange always lands in the gap), then loading /login on 15 fresh browser contexts per build:

Build Result
main's behaviour stuck on loader, exact CI failure signature ([name="email"] timeout)
fix gated on model 15/15 stuck — confirmed model is never set
fix gated on hasLoaded (this PR) 0/15 stuck, boots every run

Also reproduced the original hang locally via environment-permission-test.pw.ts against production (the test that failed on every red deploy run — it re-logs in 6+ times, so it rolls the boot race most often).

talissoncosta and others added 2 commits June 12, 2026 16:44
ConfigStore.model is never populated (getAllFlags() returns nothing at
the point config-store assigns it), so the provider always started in
the loading state even when the store had already finished loading.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The SDK's onChange can fire between the constructor reading the store
and componentDidMount subscribing to it. In E2E mode realtime, events
and analytics are disabled, so the missed event left the app on the
boot loader indefinitely. Re-read the store after subscribing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@talissoncosta talissoncosta requested a review from a team as a code owner June 12, 2026 19:49
@talissoncosta talissoncosta requested review from kyle-ssg and removed request for a team June 12, 2026 19:49
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview, Comment Jun 12, 2026 7:50pm
flagsmith-frontend-staging Ready Ready Preview, Comment Jun 12, 2026 7:50pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jun 12, 2026 7:50pm

Request Review

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-api-test:pr-7776 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-e2e:pr-7776 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api:pr-7776 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7776 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7776 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-frontend:pr-7776 Finished ✅ Results

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  43.3 seconds
commit  fda8da3
info  🔄 Run: #17473 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.5 seconds
commit  fda8da3
info  🔄 Run: #17473 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  45 seconds
commit  fda8da3
info  🔄 Run: #17473 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  1 minute, 5 seconds
commit  fda8da3
info  🔄 Run: #17473 (attempt 1)

@github-actions

Copy link
Copy Markdown
Contributor

Visual Regression

19 screenshots compared. See report for details.
View full report

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

Labels

fix front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants