You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a managed Runtime Host is installed but its process dies during startup, the Desktop handoff surface reports MANAGED_ROOT_REQUIRES_OPERATOR and asks the user to "activate it through the configured Host profile". The operator is in fact already running — it is starting the Host, and the Host is exiting immediately. The real cause is written to the service's stderr log and never reaches any surface.
This is filed for discussion rather than as a concrete fix proposal; the classification and the diagnostic plumbing are separable, and I am not sure which the project wants to change.
I hit this through a specific cause (a pinned Node runtime that cannot load @maka/storage, filed as #5424), but the misreport is independent of why the Host exits — anything that kills it before it can listen produces the same result.
Why the classification lands where it does. With the deployment installed and the Host process gone, no endpoint answers, so the client reaches the launch branch in connectOrSpawn, reads the active deployment record, and finds no launch claim:
The sawUnresponsiveEndpoint refinement immediately above already exists for the adjacent case — a managed endpoint that accepts a connection but does not answer. It does not cover this one, because when the Host dies before listening, no connection is ever accepted and sawUnresponsiveEndpoint stays false. The refusal is technically correct (this client genuinely may not spawn a replacement), but as a user-facing diagnosis it points at the wrong thing.
Why the real cause never surfaces. Three separate places drop it:
The Host can exit before any of its own code runs — an unresolved static ESM import, for example — so classifyCandidateStartupFailure (packages/runtime-host/src/candidate-startup-failure.ts) has no error to classify and no exit code to map. CANDIDATE_STARTUP_FAILURE_REASONS has no entry for "the runtime could not load the Host at all".
verifyRuntimeHostManagedServiceReady reports only its own connect failure:
// packages/cli/src/runtime-host-service-manager.ts:1336thrownewRuntimeHostServiceManagerError('service_manager_operation_failed',`Runtime Host service did not become ready: ${lastFailure}`,);
lastFailure is a client-side connect/handshake message (not available), never the service's exit status or stderr. Install, update, and repair all fail through this path, so a correctly rolled-back update reports nothing about why the new build did not come up.
The Desktop repair blocker carries only the startup error text:
resolveStartupRepair already queries the backend for activity and registration a few lines earlier, so service state is available at that point; the failure evidence is not attached.
The user-visible result is a repair dialog that loops: it offers a repair, the repair stages the next package, readiness verification times out, it rolls back, and the same MANAGED_ROOT_REQUIRES_OPERATOR text comes back. Nothing in the product ever names the actual failure, and maka runtime-host service logs — which would show it — is not reachable from the surface that is blocking.
How to reproduce
Any cause that makes the managed Host exit before it listens will do. The one I hit:
The handoff view the user is left with — note that operation: "repair" and reason: "repair_required" are correct, while diagnostic describes a different problem:
{
"target": { "name": "…", "location": "local", "rootId": "72e2fe36…" },
"state": "progress",
"reason": "repair_required",
"mayExitNaturally": false,
"operation": "repair",
"actions": ["cancel"],
"defaultAction": "cancel",
"phase": "checking",
"diagnostic": "This workspace is managed by a Runtime Host operator. Activate it through the configured Host profile. Diagnostic code: MANAGED_ROOT_REQUIRES_OPERATOR."
}
Directions that seem worth weighing, roughly in increasing cost — I have no attachment to any of them and would rather hear what fits the intended model before writing code:
Distinguish "managed but not running" from "managed, must go through the operator." Extend the existing sawUnresponsiveEndpoint refinement so that a registered deployment whose process is absent or repeatedly exiting reports something like managed_service_not_running instead. Smallest change, and it alone would stop pointing users at the Host profile.
Give an unloadable runtime a classifiable failure. A preflight in the CLI entry point, before any static import of @maka/storage, could exit with a dedicated reason in CANDIDATE_STARTUP_FAILURE_REASONS / EXIT_CODE_BY_REASON so candidateStartupFailureForExitCode can recover it. This only helps causes the entry point can anticipate, which may make it the wrong shape of fix.
Carry the evidence. Attach the backend's last exit status and a bounded, redacted tail of the service stderr to the readiness failure and to the repair blocker's diagnostic. redactSecrets and the 8 KiB bound already applied in projectBlocker give a precedent for how much is safe to surface. This is the change that would actually have told me what was wrong, but it is also the one most likely to have policy constraints I cannot see.
Happy to take any of these on if there is a preferred direction.
Investigated with Claude Code (Opus 5); the behaviour and line references above were verified against the source at fa25b3d01 and against a live reproduction on the affected machine.
What happened
When a managed Runtime Host is installed but its process dies during startup, the Desktop handoff surface reports
MANAGED_ROOT_REQUIRES_OPERATORand asks the user to "activate it through the configured Host profile". The operator is in fact already running — it is starting the Host, and the Host is exiting immediately. The real cause is written to the service's stderr log and never reaches any surface.This is filed for discussion rather than as a concrete fix proposal; the classification and the diagnostic plumbing are separable, and I am not sure which the project wants to change.
I hit this through a specific cause (a pinned Node runtime that cannot load
@maka/storage, filed as #5424), but the misreport is independent of why the Host exits — anything that kills it before it can listen produces the same result.Why the classification lands where it does. With the deployment installed and the Host process gone, no endpoint answers, so the client reaches the launch branch in
connectOrSpawn, reads the active deployment record, and finds no launch claim:The
sawUnresponsiveEndpointrefinement immediately above already exists for the adjacent case — a managed endpoint that accepts a connection but does not answer. It does not cover this one, because when the Host dies before listening, no connection is ever accepted andsawUnresponsiveEndpointstaysfalse. The refusal is technically correct (this client genuinely may not spawn a replacement), but as a user-facing diagnosis it points at the wrong thing.Why the real cause never surfaces. Three separate places drop it:
classifyCandidateStartupFailure(packages/runtime-host/src/candidate-startup-failure.ts) has no error to classify and no exit code to map.CANDIDATE_STARTUP_FAILURE_REASONShas no entry for "the runtime could not load the Host at all".verifyRuntimeHostManagedServiceReadyreports only its own connect failure:lastFailureis a client-side connect/handshake message (not available), never the service's exit status or stderr. Install, update, and repair all fail through this path, so a correctly rolled-back update reports nothing about why the new build did not come up.resolveStartupRepairalready queries the backend for activity and registration a few lines earlier, so service state is available at that point; the failure evidence is not attached.The user-visible result is a repair dialog that loops: it offers a repair, the repair stages the next package, readiness verification times out, it rolls back, and the same
MANAGED_ROOT_REQUIRES_OPERATORtext comes back. Nothing in the product ever names the actual failure, andmaka runtime-host service logs— which would show it — is not reachable from the surface that is blocking.How to reproduce
Any cause that makes the managed Host exit before it listens will do. The one I hit:
@maka/storage(see bug(cli): managed deployment pins a Node runtime without zstd support #5424 for the specific conditions).launchctl list | grep makashows the pid changing.MANAGED_ROOT_REQUIRES_OPERATOR.SyntaxErroris only in~/Library/Logs/Maka/runtime-host-services/com.maka.runtime-host.<rootId>.stderr.log.A cheaper artificial reproduction should be possible by making the configured Host entry point exit non-zero at startup.
Environment
0.2.0-dev.39.20260916, managed Runtime Host package0.2.0-dev.38.20260916fa25b3d01Logs, screenshots, or additional context
The handoff view the user is left with — note that
operation: "repair"andreason: "repair_required"are correct, whilediagnosticdescribes a different problem:{ "target": { "name": "…", "location": "local", "rootId": "72e2fe36…" }, "state": "progress", "reason": "repair_required", "mayExitNaturally": false, "operation": "repair", "actions": ["cancel"], "defaultAction": "cancel", "phase": "checking", "diagnostic": "This workspace is managed by a Runtime Host operator. Activate it through the configured Host profile. Diagnostic code: MANAGED_ROOT_REQUIRES_OPERATOR." }Directions that seem worth weighing, roughly in increasing cost — I have no attachment to any of them and would rather hear what fits the intended model before writing code:
sawUnresponsiveEndpointrefinement so that a registered deployment whose process is absent or repeatedly exiting reports something likemanaged_service_not_runninginstead. Smallest change, and it alone would stop pointing users at the Host profile.@maka/storage, could exit with a dedicated reason inCANDIDATE_STARTUP_FAILURE_REASONS/EXIT_CODE_BY_REASONsocandidateStartupFailureForExitCodecan recover it. This only helps causes the entry point can anticipate, which may make it the wrong shape of fix.diagnostic.redactSecretsand the 8 KiB bound already applied inprojectBlockergive a precedent for how much is safe to surface. This is the change that would actually have told me what was wrong, but it is also the one most likely to have policy constraints I cannot see.Happy to take any of these on if there is a preferred direction.
Investigated with Claude Code (Opus 5); the behaviour and line references above were verified against the source at
fa25b3d01and against a live reproduction on the affected machine.