Skip to content

fix(desktop): dispose orphaned PTYs on renderer crash/reload (follow-up to #48421) - #48732

Open
r266-tech wants to merge 1 commit into
NousResearch:mainfrom
r266-tech:fix-desktop-dispose-orphan-ptys-on-renderer-crash
Open

fix(desktop): dispose orphaned PTYs on renderer crash/reload (follow-up to #48421)#48732
r266-tech wants to merge 1 commit into
NousResearch:mainfrom
r266-tech:fix-desktop-dispose-orphan-ptys-on-renderer-crash

Conversation

@r266-tech

@r266-tech r266-tech commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Follow-up to merged #48421, which disposes live PTY sessions during app quit. The parallel render-process-gone crash/reload path still leaves renderer-owned shells running because reloading reuses the same webContents, so the per-session destroyed listener does not fire.

Fix

  • Port the cleanup to the current TypeScript source, apps/desktop/electron/main.ts.
  • Scope cleanup with event.sender.id, matching the webContentsId stored when each terminal starts, so another renderer's PTYs are untouched.
  • Dispose matching PTYs before both normal reload and crash-loop reload suppression.
  • Isolate per-terminal disposer and error-reporting failures so one stale PTY cannot block cleanup of the others or prevent renderer recovery.
  • Keep the existing reload window, cap, and setImmediate scheduling unchanged.

The recovery logic is extracted into a small behavior-testable helper rather than testing main.ts source text.

Validation

  • npx --no-install vitest run --project electron: 38 files, 418 passed, 1 skipped.
  • npm run typecheck: passed for renderer and Electron configs.
  • ESLint on the three touched files: 0 errors; only five pre-existing main.ts padding warnings on untouched lines.
  • git diff --check: passed.

Codex adversarial review: REWORKED then approved. The rework added independent isolation for a throwing terminal disposer and a throwing error reporter, with regressions for both.

Coordination

Open #43716 still touches the old main.cjs crash block for the distinct killed reason; it does not overlap this current-source PTY cleanup.

@alt-glitch alt-glitch added type/bug Something isn't working comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have labels Jun 19, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Disposes orphaned PTYs on renderer crash/reload by matching webContentsId and calling disposeTerminalSession before the reload/suppress branches. Follows the before-quit sweep pattern. Clean 1-file fix in the Electron main process.


Reviewed by Hermes Agent

@alt-glitch alt-glitch added comp/desktop Electron desktop app (apps/desktop/*) and removed comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels Jun 26, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracing the renderer-crash lifecycle and reusing the existing idempotent PTY disposer. The underlying gap remains on current main: apps/desktop/electron/main.ts:7312-7335 reloads a crashed/oom renderer, while terminal cleanup is otherwise tied to event.sender.once('destroyed', ...) at apps/desktop/electron/main.ts:8612.

Problems

  • The diff changes apps/desktop/electron/main.cjs, but Desktop's source was renamed and substantially migrated to apps/desktop/electron/main.ts in 39d09453f95e8aefc0c97e5d9b30ff341cae9ed8. The current bundle path therefore receives none of this PR as written.
  • No current Electron test covers render-process-gone disposal; the PR adds none.

Suggested changes

  • Port the sweep to apps/desktop/electron/main.ts:7312, before the limiter/reload path, and scope it with the event sender id recorded at apps/desktop/electron/main.ts:8597.
  • Add focused coverage for disposal before both reload and reload suppression.

This is an automated hermes-sweeper review.

Comment thread apps/desktop/electron/main.cjs Outdated
// would leak a live shell (plus children/handles) on every crash. Dispose
// them here, scoped by the stored webContentsId, mirroring the before-quit
// sweep. Runs before the reload/suppress branches so it covers both.
const goneWebContentsId = mainWindow?.webContents?.id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This source file was renamed to apps/desktop/electron/main.ts by 39d09453f95e8aefc0c97e5d9b30ff341cae9ed8; current Desktop bundles the TypeScript entrypoint, so this block must be ported there to affect the product. While porting, scope with the render-process-gone event sender id, which is the id stored for terminal sessions.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
@r266-tech
r266-tech force-pushed the fix-desktop-dispose-orphan-ptys-on-renderer-crash branch from d4aea69 to 464bb20 Compare July 15, 2026 01:24
@r266-tech

Copy link
Copy Markdown
Contributor Author

Addressed the current-source and test requests in 464bb20a7:

  • ported the crash cleanup from removed main.cjs to main.ts;
  • scoped it to event.sender.id, matching terminal session webContentsId;
  • added behavior coverage proving cleanup runs before both reload and reload-loop suppression and does not touch another renderer's PTYs;
  • kept recovery running if a terminal disposer or its error reporter throws.

Verification: all Electron Vitest tests passed (418 passed, 1 skipped), Desktop typecheck passed, touched-file ESLint has 0 errors, and git diff --check passed. Codex adversarial review found the two failure-isolation gaps above; both were reworked and the final review approved.

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

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants