Skip to content

fix: destroy leaked fragment-capture window on failed loadURL - #14

Open
murich wants to merge 1 commit into
HelpFreedom:mainfrom
murich:fix/fragment-capture-leak-on-load-failure
Open

fix: destroy leaked fragment-capture window on failed loadURL#14
murich wants to merge 1 commit into
HelpFreedom:mainfrom
murich:fix/fragment-capture-leak-on-load-failure

Conversation

@murich

@murich murich commented Sep 1, 2026

Copy link
Copy Markdown

Summary

  • captureStart() in electron/fragments.ts registered the offscreen fragment-capture BrowserWindow in the captures map before awaiting win.loadURL(url). A rejected load (e.g. the fragment dev server briefly unavailable) left the window alive and untracked, and the captures.has(id) early-return then permanently blocked any retry for that fragment id.
  • Enough leaked, continuously-painting capture windows accumulating can starve the single shared GPU process — observed as the preview going solid black with no exception, no crash, and no log output, since the existing webglcontextlost/webglcontextrestored recovery in player.ts only fires on an actual context reset, not GPU-process starvation.
  • Fix: wrap the loadURL await in try/catch, destroy and unregister the window on failure, then rethrow so the caller still sees the error.

Test plan

  • npx tsc --noEmit -p tsconfig.node.json passes
  • Manually repro by pointing captureStart at an unreachable URL and confirming the window is destroyed and a retry succeeds

captureStart() registered the offscreen capture BrowserWindow in the
captures map before awaiting win.loadURL(url). If the load rejected
(e.g. the fragment dev server was momentarily unavailable), the window
was never destroyed or removed, and captureStart's own
captures.has(id) early-return then permanently blocked any future
retry for that fragment id.

The leaked window keeps compositing on the GPU indefinitely. Enough of
them accumulating (repeated capture attempts against a flaky dev
server) can starve the single shared GPU process, which manifests as
the preview going solid black with no exception and no crash — the
existing webglcontextlost/webglcontextrestored recovery in
player.ts never fires because the GPU process is starved, not reset.

Wrap the loadURL await in try/catch and destroy+unregister the window
on failure before rethrowing, so a failed load is fully cleaned up
and can be retried.
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