fix(desktop): isolate runtime plugin render hooks - #82763
Merged
Merged
Conversation
teknium1
added a commit
that referenced
this pull request
Aug 11, 2026
…nder() isolation class Three-part class closure for the React #310 / lost-renderer-crash family (#79428, follow-up to #80560 / #82763): 1. Diagnosability (#79428 defect B): error-boundary catches now persist to desktop.log with their component stack via a new fire-and-forget hermes:logs:renderer-error IPC (synchronous flush — the window may be dying). Every renderer-content window (main, secondary session, instance, HUD, quick entry, pet overlay) gets the error-level console capture that previously only the main window had, labeled per window. 'Open logs' on the crash dialog now reveals a file that actually contains the crash. 2. Recurrence guard: eslint no-restricted-syntax rule banning inline render() calls in JSX — the mechanism behind #80560. The rule immediately caught two live sites #82763's audit missed (floating panes, narrow-overlay reveal), both hosting plugin panes. 3. Fix those two missed sites with the same ContribRender mount. extracted console-capture/report formatting to electron/renderer-log.ts with unit tests; renderer console lines now carry the window label.
blut-agent
pushed a commit
to blut-agent/hermes-agent-fork
that referenced
this pull request
Aug 11, 2026
…nder() isolation class Three-part class closure for the React NousResearch#310 / lost-renderer-crash family (NousResearch#79428, follow-up to NousResearch#80560 / NousResearch#82763): 1. Diagnosability (NousResearch#79428 defect B): error-boundary catches now persist to desktop.log with their component stack via a new fire-and-forget hermes:logs:renderer-error IPC (synchronous flush — the window may be dying). Every renderer-content window (main, secondary session, instance, HUD, quick entry, pet overlay) gets the error-level console capture that previously only the main window had, labeled per window. 'Open logs' on the crash dialog now reveals a file that actually contains the crash. 2. Recurrence guard: eslint no-restricted-syntax rule banning inline render() calls in JSX — the mechanism behind NousResearch#80560. The rule immediately caught two live sites NousResearch#82763's audit missed (floating panes, narrow-overlay reveal), both hosting plugin panes. 3. Fix those two missed sites with the same ContribRender mount. extracted console-capture/report formatting to electron/renderer-log.ts with unit tests; renderer console lines now carry the window label.
skappafrost
pushed a commit
to skappafrost/hermes-agent
that referenced
this pull request
Aug 15, 2026
…nder() isolation class Three-part class closure for the React NousResearch#310 / lost-renderer-crash family (NousResearch#79428, follow-up to NousResearch#80560 / NousResearch#82763): 1. Diagnosability (NousResearch#79428 defect B): error-boundary catches now persist to desktop.log with their component stack via a new fire-and-forget hermes:logs:renderer-error IPC (synchronous flush — the window may be dying). Every renderer-content window (main, secondary session, instance, HUD, quick entry, pet overlay) gets the error-level console capture that previously only the main window had, labeled per window. 'Open logs' on the crash dialog now reveals a file that actually contains the crash. 2. Recurrence guard: eslint no-restricted-syntax rule banning inline render() calls in JSX — the mechanism behind NousResearch#80560. The rule immediately caught two live sites NousResearch#82763's audit missed (floating panes, narrow-overlay reveal), both hosting plugin panes. 3. Fix those two missed sites with the same ContribRender mount. extracted console-capture/report formatting to electron/renderer-log.ts with unit tests; renderer console lines now carry the window label.
melon-xf
added a commit
to melon-xf/hermes-agent
that referenced
this pull request
Sep 3, 2026
…nder() isolation class Three-part class closure for the React NousResearch#310 / lost-renderer-crash family (NousResearch#79428, follow-up to NousResearch#80560 / NousResearch#82763): 1. Diagnosability (NousResearch#79428 defect B): error-boundary catches now persist to desktop.log with their component stack via a new fire-and-forget hermes:logs:renderer-error IPC (synchronous flush — the window may be dying). Every renderer-content window (main, secondary session, instance, HUD, quick entry, pet overlay) gets the error-level console capture that previously only the main window had, labeled per window. 'Open logs' on the crash dialog now reveals a file that actually contains the crash. 2. Recurrence guard: eslint no-restricted-syntax rule banning inline render() calls in JSX — the mechanism behind NousResearch#80560. The rule immediately caught two live sites NousResearch#82763's audit missed (floating panes, narrow-overlay reveal), both hosting plugin panes. 3. Fix those two missed sites with the same ContribRender mount. extracted console-capture/report formatting to electron/renderer-log.ts with unit tests; renderer console lines now carry the window label.
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
Root cause
Desktop hosts called plugin
render()callbacks while rendering the host component. A hook used by a plugin therefore became a hook of the host. Loading or replacing a plugin changed the host's hook count and could trigger React error #310. It also meant a render-time plugin exception occurred beforeContribBoundaryreceived its child, so the boundary could not contain the failure.ContribRenderpasses the callback tocreateElement, giving each contribution its own component boundary. Replacing a callback now remounts that child instead of changing the host's hook order, and plugin exceptions occur belowContribBoundary.I audited every production
.render()contribution call underapps/desktop/src; no direct callback invocation remains.Fixes #80560
Verification
npx vitest run --project ui src/contrib/react/slot.test.tsx- 2 passednpm run typecheck- passednpm run lint- 0 errors (89 pre-existing warnings)npm run build- passed, includingassert-dist-builtgit diff --check origin/main...HEAD- passedThe full Desktop UI run completed with 3,624 passing tests and 8 aggregate timeout/order failures in four unrelated existing files. Each affected file passes in a fresh process (19/19 total); the intermittent messaging file also passes on untouched exact-base
main(7/7).