Title: Infinite recursion between TriggerUncaughtException and InspectorConsoleCall when console.error throws · Issue #64326 · nodejs/node · GitHub
Open Graph Title: Infinite recursion between TriggerUncaughtException and InspectorConsoleCall when console.error throws · Issue #64326 · nodejs/node
X Title: Infinite recursion between TriggerUncaughtException and InspectorConsoleCall when console.error throws · Issue #64326 · nodejs/node
Description: Version v26.3.0 (also hit this on v22 macOS 15) Platform Darwin TS-Temuulen-2.local 25.5.0 Darwin Kernel Version 25.5.0: Fri Jun 5 02:15:17 PDT 2026; root:xnu-11471.122.99.501.2~1/RELEASE_ARM64_T6000 arm64 arm Subsystem V8 / Inspector / ...
Open Graph Description: Version v26.3.0 (also hit this on v22 macOS 15) Platform Darwin TS-Temuulen-2.local 25.5.0 Darwin Kernel Version 25.5.0: Fri Jun 5 02:15:17 PDT 2026; root:xnu-11471.122.99.501.2~1/RELEASE_ARM64_T60...
X Description: Version v26.3.0 (also hit this on v22 macOS 15) Platform Darwin TS-Temuulen-2.local 25.5.0 Darwin Kernel Version 25.5.0: Fri Jun 5 02:15:17 PDT 2026; root:xnu-11471.122.99.501.2~1/RELEASE_ARM64_T60...
Opengraph URL: https://github.com/nodejs/node/issues/64326
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Infinite recursion between TriggerUncaughtException and InspectorConsoleCall when console.error throws","articleBody":"### Version\n\nv26.3.0 (also hit this on v22 macOS 15)\n\n### Platform\n\nDarwin TS-Temuulen-2.local 25.5.0 Darwin Kernel Version 25.5.0: Fri Jun 5 02:15:17 PDT 2026; root:xnu-11471.122.99.501.2~1/RELEASE_ARM64_T6000 arm64 arm\n\n### Subsystem\n\nV8 / Inspector / Process\n\n### What steps will reproduce the bug?\n\nHard to nail down to a single script — it's non-deterministic. But here's what triggers it:\n\nA native addon (in my case Turbopack via napi-rs ThreadSafeFunction) calls a JS callback that has a pending exception. Instead of handling the error normally, the process locks up.\n\nI caught it with `sample` while it was spinning at 94% CPU. Here's the stack:\n\n```\nuv_run → uv__io_poll → uv__async_io\n → ThreadSafeFunction::AsyncCb\n → CallbackScope::~CallbackScope\n → InternalCallbackScope::Close\n → v8::Function::Call\n → Execution::Call → Invoke\n → Isolate::ReportPendingMessages\n → MessageHandler::ReportMessage\n → TriggerUncaughtException\n → v8::Function::Call\n → Execution::Call → Invoke\n → Builtins_JSEntry\n → InspectorConsoleCall\n → v8::Function::Call (← re-enters TriggerUncaughtException)\n```\n\nThe pattern is clear: `TriggerUncaughtException` reports via the inspector console, `InspectorConsoleCall` itself throws, and that throw goes right back into `TriggerUncaughtException`. Forever.\n\nYou'd probably need a napi-rs addon with a ThreadSafeFunction that calls into JS and throws, with the inspector/profiler attached during the call. Something like:\n\n```js\nconst addon = require('bindings')('addon.node')\n// addon.startWorker(callbackThatThrows) while inspector is connected\n```\n\n### How often does it reproduce? Is there a required condition?\n\nNon-deterministic. Roughly 1 in 3 dev server restarts for me. Required conditions:\n\n- A native addon callback that throws\n- Inspector protocol active (dev tools or Node inspector)\n- Inspector connection has to be in a state where `InspectorConsoleCall` fails\n\n### What is the expected behavior? Why is that the expected behavior?\n\n`TriggerUncaughtException` should not be re-entrant through the inspector. If the inspector console itself throws during error reporting, Node should detect the re-entrance and either:\n\n- Fall back to writing to stderr directly (bypasses inspector entirely)\n- Or crash with `process.abort()` so at least it's obvious\n\nA `console.error` inside error handling should never be able to loop back into `TriggerUncaughtException`. That path should be guarded.\n\n### What do you see instead?\n\nThe process pegs a CPU core at 94-100%. RSS starts around 150MB and grows to 2.2GB+ — keeps allocating because V8's exception machinery keeps running. The machine starts swapping. `kill` (SIGTERM) does nothing, have to `kill -9` it. Meanwhile the entire system slows to a crawl from memory pressure.\n\n### Additional information\n\n- The workaround is replacing `console.error` with `process.stderr.write` in error handlers — it bypasses the inspector protocol breakage entirely\n- Same loop pattern reported in cdp-tools-mcp #74 (v0.4.3 patch)\n- This isn't specific to Next.js or Turbopack — any native addon with async callbacks can trigger it under the right conditions\n","author":{"url":"https://github.com/themuuln","@type":"Person","name":"themuuln"},"datePublished":"2026-07-06T15:30:22Z","url":"https://github.com/nodejs/node/issues/64326"}
| react-profiling | 0 |
| react-import-map | react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf |
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:75b32e7c-271d-8990-fb5a-f31ab4108699 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | BC46:143C91:793A27:A1657E:6AED2441 |
| html-safe-nonce | f37c1c808474ef2d77b10742ea44b2f0e5e90d8355d72818e40733486e3260e2 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCQzQ2OjE0M0M5MTo3OTNBMjc6QTE2NTdFOjZBRUQyNDQxIiwidmlzaXRvcl9pZCI6IjM2NjUzNDI2NDE0MzY2OTc2NjUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | f1ede18c8b20bec8bff1c912749d1f0ba1bf8d517743e07803346937355e2f00 |
| hovercard-subject-tag | issue:4820628186 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/64326/issue_layout |
| twitter:image | https://opengraph.githubassets.com/0d885721c4a6f97b14c0df91c644ce5203685e1be343eefb5a3ccbfb3d3ae492/nodejs/node/issues/64326 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/0d885721c4a6f97b14c0df91c644ce5203685e1be343eefb5a3ccbfb3d3ae492/nodejs/node/issues/64326 |
| og:image:alt | Version v26.3.0 (also hit this on v22 macOS 15) Platform Darwin TS-Temuulen-2.local 25.5.0 Darwin Kernel Version 25.5.0: Fri Jun 5 02:15:17 PDT 2026; root:xnu-11471.122.99.501.2~1/RELEASE_ARM64_T60... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | themuuln |
| hostname | github.com |
| expected-hostname | github.com |
| None | e3e0f7f63e50c6fe879198a93a0a023a648ecc0a5e9bc3b5e033ac57172237e6 |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 707a24b346ac8a82878b9c084efaa38a997660cb |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
| react-app-name | issues |
Links:
Viewport: width=device-width