Skip to content

Frontend: desync recovery dispatches events nobody listens to (UI stuck after WS drop) #224

Description

@hydropix

Summary

The visibility-based desync recovery dispatches CustomEvents that nobody listens to, so when the WebSocket drops during job completion the UI stays stuck on "Batch in Progress" until the page is reloaded.

Where

  • src/web/static/js/utils/lifecycle-manager.js:228,240 (checkStateConsistency dispatches new CustomEvent('translationUpdate', …) and new CustomEvent('resetUIToIdle') on window)
  • The real handler is TranslationTracker.handleTranslationUpdate, wired only to the socket event translation_update — not to a window translationUpdate event.

Details

checkStateConsistency() runs every 10 s and on tab re-focus. It correctly detects that the server finished/errored a job while the UI still thinks it's running, then fires window CustomEvents — but a repo-wide grep confirms zero listeners for translationUpdate or resetUIToIdle. So the recovery logs "state desync — syncing" and then does nothing.

Impact

A user whose WebSocket dropped during completion keeps a stuck "Batch in Progress" UI (Translate button disabled) until they reload.

Suggested fix

Call the real handlers directly from checkStateConsistencyTranslationTracker.handleTranslationUpdate(payload) and the actual idle-reset routine — instead of dispatching events with no subscribers. (See the related issue about lifecycle state being smeared across four modules.)


Found during the June 2026 repo audit. Severity: high. Confidence: certain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — fix soonaudit-2026-06Found during the June 2026 repo auditbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions