fix(session): make eager status backfill opt-in - #1040
Open
duckvhuynh wants to merge 1 commit into
Open
Conversation
duckvhuynh
marked this pull request as ready for review
August 2, 2026 01:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 makes the eager WhatsApp Status history backfill on session
readyopt-in instead of unconditional.On an affected freshly paired
whatsapp-web.jsaccount, OpenWA reachedREADYsuccessfully but WhatsApp revoked the companion at the first scheduled WhatsApp Web reload, approximately five minutes later. After isolating OpenWA-specific work performed duringready, the trigger was narrowed to the immediatestatus@broadcasthistory read used to seed the Status store.Disabling only that read allowed the same account, browser, container, Web build, and production configuration to survive the reload and remain connected. Live Status events continue to work; only the one-time backfill of statuses that predate the connection is disabled by default.
Related to #982. This is a follow-up to the onboarding-modal handling in #998: auto-dismissing the modal improved onboarding visibility but did not stop the deterministic logout for this account.
Problem
Observed behavior
For the affected account, every fresh pairing followed the same sequence:
whatsapp-web.jsemitsauthenticatedandready.READYand the page is usable.CONNECTEDwithhasSynced=trueand a validWWebJSruntime.?post_logout=1&logout_reason=0.whatsapp-web.jsemitsdisconnected: LOGOUT, removes the LocalAuth profile, and OpenWA can only return to a fresh QR.The result is a deterministic loss of credentials after an apparently successful link. Container restarts, reconnect retries, and persistent volumes cannot recover the session because
whatsapp-web.jsdeletes the credentials after the WhatsApp-side logout.Investigation and root-cause isolation
The following possible causes were tested and did not change the outcome:
openwaOS user, and the production Chromium flags;readyreconciliation versus the original enginereadyevent;Two controls were important:
whatsapp-web.jsclient, run inside the same production container with the same Chrome binary, OS user, account, and WhatsApp Web build, survived its five-minute reload.whatsapp-web.jsclient also survived the same reload and stayed authenticated.The relevant behavioral difference was in
SessionService.handleEngineReady(). OpenWA immediately ran:That eager history fetch happens after the new companion becomes ready but before its first scheduled Web reload.
Single-variable A/B test
The production-equivalent test was repeated with only the eager Status seed changed:
readypost_logout=1, emittedLOGOUT, removed the linked device, and deleted LocalAuthCONNECTED/hasSynced; no logout occurred and credentials remained presentSuccessful run timeline:
READYCONNECTED,hasSynced=true, withWWebJSavailableREADY; nopost_logout, noLOGOUT, and the profile remained intactThis does not imply that every WhatsApp account is rejected by the history request. It establishes that, for affected accounts, the immediate
status@broadcastfetch is the causal OpenWA-side trigger. Because the backfill is optional enrichment rather than a session-readiness requirement, making it opt-in is the safer default.Changes
Session behavior
STATUS_SEED_ON_READYparsing with the accepted truthy valuestrue,1,yes, andon.seedStatuses()when the variable is absent or false.status_seed_on_ready_disabledwhen the backfill is skipped.Configuration
STATUS_SEED_ON_READY=falsein.env.example.docker-compose.yml, defaulting tofalse.Documentation
Tests
readyby default.Compatibility and tradeoffs
Validation
Automated checks on this branch
npx eslint src/modules/session/session.service.ts src/modules/session/session.service.spec.ts— passed.npm test -- --runInBand src/modules/session/session.service.spec.ts— 236/236 passed.docker compose -f docker-compose.yml config --quiet— passed.git diff --cached --check— passed (only local Windows LF/CRLF conversion notices).Production-equivalent runtime checks
v0.12.2and rebuilding, the existing linked profile restored automatically and reachedREADYin about four seconds without a new QR.status_seed_on_ready_disableddebug event.Existing upstream build issue observed locally
npm run buildcurrently stops at an unrelated TypeScript error insrc/engine/adapters/whatsapp-web-js.adapter.ts:523, wheremsg.downloadMedia()can resolveundefinedbutresolveBoundedaccepts onlyMessageMedia | null. That file is byte-for-byte unchanged fromupstream/mainin this branch and is outside this PR's diff. The completeSessionServicetest suite and lint checks for the changed TypeScript files pass.Rollout
No action is required for affected installations after updating: the safer behavior is the default. Operators who intentionally depend on pre-connection Status history should enable
STATUS_SEED_ON_READY=trueafter validating that their accounts remain linked through the first scheduled WhatsApp Web reload.