Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate of this identified retention path. Related closed reports: [Bug]: macOS renderer grows to ~4 GB RSS over a long multi-thread session, then crashes with EXC_BREAKPOINT (SIGTRAP) in node::Environment::allocate_managed_buffer #17295 and [Bug]: macOS desktop app grows to ~139.5 GB memory, triggers "system has run out of application memory" #29638 describe memory growth, but do not establish this closure ownership cause. This report does not attribute those failures to this path.
- I included enough detail to reproduce or investigate the problem.
Area
apps/web
Steps to reproduce
- At the commit below, run an isolated desktop development instance with synthetic Replay (dev) threads, including long transcripts and real delegated children. Keep several Replay turns streaming while typing and switching between long and child threads.
- Capture renderer heap snapshots with explicit GC. Keep the inspector session connected while reopening a long thread, navigating to a draft, and waiting beyond the thread snapshot retention TTL.
- Inspect the retained ChatView render contexts and their concrete closure edges. The same context family appears during the full-hour streaming baseline.
- Observe old ChatView contexts linking through render-created focus, optimistic-message and settings-persistence callbacks, including the returned lifecycle and send-hook callbacks.
The sanitized workload, process-memory charts, normalization and limitations are in https://hsa8po25c8rd.postplan.dev . The pre-code scope decision is in https://uaafzwf12as8.postplan.dev . Raw snapshots remain private because heap files can contain conversation data.
Expected behavior
Long-lived callbacks should preserve their existing latest-event or origin-thread semantics without keeping a growing chain of obsolete render data alive. Thread switching, draft promotion, focus, typing and streaming should remain smooth.
Actual behavior
The development renderer retains a chain of historical ChatView and hook contexts through callbacks invalidated at different times. A saved same-isolate post-TTL heap contains a concrete obsolete context retaining another obsolete context via focusComposer; both retain raw send-routing closures. The pre-edit assertion of the no-historical-context-chain invariant fails on that edge.
The window focus effect removes its listener correctly. The production web registry releases per-thread state on time. Bounded markdown and timeline caches are separate owners. This report does not claim a leaked listener, an unbounded cache, or a demonstrated production RAM saving. Development module/source retention contributes substantial background heap. The production candidate ownership and material shipped-client benefit remain to be proven.
Impact
Major degradation or frequent failure
Version or commit
Environment
Isolated Linux x86_64 development VM; Electron 44.10.1, Node v26.12.1, pnpm 12.14.0. Free Replay (dev) workload. A separate locally built production web lifecycle check ran in Chromium.
Logs or stack traces
The saved-client assertion fails on a concrete ChatView context → focusComposer closure → older ChatView context edge. Window/document/main anchors remain stable across the lifecycle snapshots. The desktop lifecycle process validator separately remains failed for an Electron-as-Node server PID classification; that failure is not relabeled green and does not establish client RSS attribution by itself. Details and raw-sample charts are linked above.
Screenshots, recordings, or supporting files
Sanitized reports linked above. No private heap files uploaded.
Workaround
Reloading the client releases its renderer state, but loses the opportunity to keep a long session open. No verified product fix yet.
Activity