Skip to content

runtime-host: resource query failure can crash the host during reentrant session admission #4656

Description

@Sun-GLiang

What happened

Maka Desktop displayed the following error when opening a task:

读取任务失败
任务内容暂时无法读取,请稍后重试。

The task data itself was not shown to be corrupt. Instead, the local Runtime Host exited with code 1 while handling a failed runtime.resource.query.

A resource-query failure calls requestDrain() while still executing inside SessionAdmissionGate.run(). Draining the Agent Graph then attempts to stop its operator sessions, which calls SessionManager.stopSession() and re-enters the same admission gate.

The gate rejects the nested admission:

Error: Cannot enter Session admission from an active admission; reuse its lease instead

However, SessionManager.stopSession() stores that rejected promise in ownStop, performs asynchronous child-session lookup, and only awaits ownStop afterward. This creates an unhandled-rejection window. Node terminates the Runtime Host process before the outer Promise.allSettled() can contain the failure.

Once the Runtime Host exits, active session subscriptions and transcript reads lose their transport connection, causing the Desktop error above.

Expected behavior:

  • A Runtime Resource read failure may return internal_failure, but must not crash the Runtime Host.
  • Host draining must not re-enter an active Session admission without reusing its lease or leaving the admission context first.
  • Rejected stop promises must be observed immediately.
  • The original resource-read error should be preserved in diagnostics instead of being replaced by a generic message.

How to reproduce

Observed with an Agent Graph containing operator sessions:

  1. Run Maka Desktop from source.
  2. Open a task whose Agent Graph contains one or more operator sessions.
  3. Cause runtime.resource.query / shell-runs:list to fail while it is executing inside SessionAdmissionGate.run().
  4. The query error handler calls requestDrain().
  5. Agent Graph draining calls stopSession() for the known operators.
  6. The Runtime Host exits with code 1.
  7. Desktop session observation and transcript requests fail with connection_closed, and the task displays 读取任务失败.

The original resource-read failure was not retained in the diagnostic report, so the exact condition that caused the first listShellRunUpdates() failure is currently unknown.

The crash reproduced across three automatically started Runtime Host candidates in the captured report, at approximately 11:38:04, 11:38:08, and 11:38:36.

Relevant call chain:

HostRuntimeResourceCoordinator.#query
  -> SessionAdmissionGate.run
  -> requestDrain
  -> AgentGraphCoordinator.beginDrain
  -> #stopKnownOperators
  -> SessionManager.stopSession
  -> RootTurnCoordinator.stopSession
  -> SessionAdmissionGate.run
  -> rejected nested admission
  -> unhandled rejection
  -> Runtime Host exits

Relevant locations:

  • packages/runtime-host/src/server/runtime-resource-coordinator.ts:305-347
  • packages/runtime-host/src/server/session-admission-gate.ts:49-60
  • packages/runtime/src/stream-graph-coordinator.ts:643-675
  • packages/runtime/src/stream-graph-coordinator.ts:1619-1634
  • packages/runtime/src/session-manager.ts:3584-3607
  • packages/runtime-host/src/server/root-turn-coordinator.ts:945-990

Environment

  • Maka version: 0.2.0
  • Reproduced commit: d4b28b148
  • Latest upstream main inspected: cd4aa3d8f
  • Reproduction status on latest main: the failure path remains present by source inspection; a full Desktop runtime reproduction has not yet been performed on that commit
  • Build/channel: dev
  • Surface: Desktop / Runtime Host
  • OS: macOS Darwin 24.6.0, arm64
  • Electron: 43.4.1
  • Chrome: 150.0.7871.224
  • Node.js: 24.18.1
  • Locale: zh-CN

Logs, screenshots, or additional context

Relevant Runtime Host error:

Error: Cannot enter Session admission from an active admission; reuse its lease instead
    at SessionAdmissionGate.run
    at RootTurnCoordinator.stopSession
    at SessionManager.stopSession
    at AgentGraphCoordinator.#stopKnownOperators

This was followed by:

[runtime-host] candidate exited unexpectedly { code: 1, signal: null }
Runtime Host connection closed: Runtime Host transport read side ended

The preceding models.dev no longer carries ...; adopting upstream message appears informational and is not on the failure path.

Read-only checks against the current workspace database found:

  • PRAGMA quick_check: ok
  • 701 ShellRun records successfully normalized
  • 6,500 stored messages successfully decoded, including chunked messages
  • No invalid JSON or foreign-key violations in the relevant tables

There is therefore no current evidence of physical database or persisted ShellRun/message corruption.

A minimal timing check confirms that the current SessionManager.stopSession() ordering exposes an already-rejected ownStop promise as unhandled before the later await ownStop.

Two defensive fixes may be needed:

  1. Do not synchronously initiate Host drain from inside an active Session admission when draining can call back into the same gate.
  2. Attach a rejection handler to ownStop immediately, or restructure stopSession() so all started stop operations are observed from the moment they are created.

Diagnostics should additionally record the original exception currently hidden by the catch { ... } blocks in HostRuntimeResourceCoordinator.#query.

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions