What happened
The Electron main process crashed with JavaScript heap out of memory after ~12 hours of uptime. The hours leading up to the crash are dominated by hundreds of repeated [runtime-host] MCP capability alignment failed errors.
Each of those log lines corresponds to exactly one mcpCapabilityPublisher.bind() call inside registerHostClientIpc() (apps/desktop/src/main/runtime-host-boot.ts), i.e. one full Runtime Host candidate generation. Hundreds of generations over ~12h means the host connection was flapping continuously:
- Every generation's
client.capability.replace fails with RuntimeHostRequestInterruptedError (dispatch: 'not_dispatched', reason: 'connection_lost'), caused by RuntimeHostTransportError: read_eof ("Runtime Host transport read side ended") or occasionally read_timeout.
- The desktop side respawns candidates via the reconnect lifecycle (backoff capped at 5s, no circuit breaker) and re-runs the full registration stack each time.
Per-generation cleanup is wired to candidate close (disposeClientIpc → unsubscribe + map deletion in runtime-host-boot.ts, removeHandler in runtime-host-reconnecting-ipc-main.ts, observer/provider teardown in runtime-host-desktop-candidate.ts). The OOM therefore indicates that some retention still accumulates across this churn. Pinning the exact retained root will need a heap snapshot under reproduction.
Expected behavior:
- Long uptime with a flapping/unavailable Runtime Host must not exhaust the main-process heap.
- A candidate that dies immediately after spawn should trigger backoff escalation / circuit-breaking instead of unbounded regeneration.
How to reproduce
- Run desktop from source on Windows:
npm run dev:hmr in apps/desktop.
- Leave it running for many hours while the Runtime Host connection keeps dropping (host transport read side ends repeatedly; root cause of the flapping itself is not yet identified).
- Observe hundreds of
[runtime-host] MCP capability alignment failed errors and steady main-process heap growth until V8 OOM.
Environment
- Maka version or commit: workspace
@maka/desktop@0.1.11, run from source (exact commit at crash time not captured)
- OS and version: Windows
- Surface: Desktop (Electron main process)
- Node.js version, if running from source: Electron-bundled Node (crash raised via
node_bindings.cc)
Logs, screenshots, or additional context
Crash:
[5420:...] 42867680 ms: Mark-Compact (reduce) 3612.6 (3948.2) -> 3612.6 (3887.0) MB ... last resort; GC in old space requested
[5420:...] ERROR:electron\shell\common\node_bindings.cc:189] OOM error in V8: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Representative repeating error (trimmed):
[runtime-host] MCP capability alignment failed: RuntimeHostRequestInterruptedError:
Runtime Host client.capability.replace was interrupted: the operation was not dispatched
operation: 'client.capability.replace', mode: 'command',
dispatch: 'not_dispatched', reason: 'connection_lost', retryable: false,
[cause]: RuntimeHostTransportError: Runtime Host transport read side ended
at #endRead (.../runtime-host/dist/transport/framed-transport.js:189:30)
code: 'read_eof'
Some late errors switch to read_timeout, consistent with the event loop degrading as the heap fills.
Areas worth instrumenting first during the fix:
- module-level maps in
runtime-host-boot.ts keyed by target / targetEpoch across generations;
- the promise-chain queue in
runtime-host-capability-revision-publisher.ts;
- per-generation session observation registry / native provider sets;
- reconnect lifecycle churn without escalation when a candidate dies at startup.
What happened
The Electron main process crashed with
JavaScript heap out of memoryafter ~12 hours of uptime. The hours leading up to the crash are dominated by hundreds of repeated[runtime-host] MCP capability alignment failederrors.Each of those log lines corresponds to exactly one
mcpCapabilityPublisher.bind()call insideregisterHostClientIpc()(apps/desktop/src/main/runtime-host-boot.ts), i.e. one full Runtime Host candidate generation. Hundreds of generations over ~12h means the host connection was flapping continuously:client.capability.replacefails withRuntimeHostRequestInterruptedError(dispatch: 'not_dispatched',reason: 'connection_lost'), caused byRuntimeHostTransportError: read_eof("Runtime Host transport read side ended") or occasionallyread_timeout.Per-generation cleanup is wired to candidate close (
disposeClientIpc→ unsubscribe + map deletion inruntime-host-boot.ts,removeHandlerinruntime-host-reconnecting-ipc-main.ts, observer/provider teardown inruntime-host-desktop-candidate.ts). The OOM therefore indicates that some retention still accumulates across this churn. Pinning the exact retained root will need a heap snapshot under reproduction.Expected behavior:
How to reproduce
npm run dev:hmrinapps/desktop.[runtime-host] MCP capability alignment failederrors and steady main-process heap growth until V8 OOM.Environment
@maka/desktop@0.1.11, run from source (exact commit at crash time not captured)node_bindings.cc)Logs, screenshots, or additional context
Crash:
Representative repeating error (trimmed):
Some late errors switch to
read_timeout, consistent with the event loop degrading as the heap fills.Areas worth instrumenting first during the fix:
runtime-host-boot.tskeyed by target /targetEpochacross generations;runtime-host-capability-revision-publisher.ts;