Repository navigation
fix(native): report a stopped runtime from ps and print closed errors without a stack - #325
Merged
Merged
Conversation
… without a stack
A stopped candidate runtime made `hack ps` exit 1 with the native refusal
printed twice and a raw JavaScript stack trace. A stopped runtime is an
ordinary state for a read-only status command.
- Image-native and authored `ps` treat `runtime_not_running` as a status:
exit 0, a one-line "Native runtime is not running; no services are
running." note plus the empty table, and status `runtime_not_running`
(saved run, null phase, no items). Other native refusals still fail.
- Image-native `ps --json` now prints the standard `{ok: true, data}`
envelope, matching authored native ps. The acceptance driver unwraps it.
- Native `logs --no-follow` (image and authored) refuse a stopped runtime
with `E_DOCKER_UNAVAILABLE` and a closed message.
- NativeRuntimeRequestError and native observe refusals are ClosedCliError:
the top-level handler prints their message once, with the stack only
under HACK_DEBUG=1. HackCliError also shows its stack under HACK_DEBUG=1.
Unexpected exceptions keep printing their stack.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… generic refusal The held saved-read owner turns every error raised inside it into its own artifact refusal, so authored `logs --no-follow` against a stopped runtime printed E_LIFECYCLE_FAILED and the E_DOCKER_UNAVAILABLE mapping in runAuthoredLogs was unreachable. The read now keeps a runtime_not_running reply as a value, rechecks the saved selection and executable, and rethrows it after the owner closes. Tests: source CLI authored logs against a stopped fake runtime (human and --json: E_DOCKER_UNAVAILABLE, exit 1, one line, no stack); a stopped reply after executable drift refuses; authored ps refuses saved-selection or executable drift that precedes a stopped-runtime reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
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.
Problem
On the M3, with a native candidate built from
nextand the native runtime stopped,hack-v5 ps --path <project> --branch alphaexited 1. It printed the closed native refusalNative runtime request failed (runtime_not_running); inspect owned state before retrying., then printed it again asERROR: Error: …followed by a raw JavaScript stack trace. A stopped runtime is an ordinary state for a read-only status command.Cause:
nativeProjectPslet thegraph inspectrefusal propagate.NativeRuntimeRequestErrorwas a plainError, so the top-level handler took the "unexpected exception" path, which callscancel(message)and then printserror.stack.Change
ps (image-native and authored)
runtime_not_running,psexits 0. It reports statusruntime_not_runningwith the savedrun, a nullphaseand noitems. Text output printsNative runtime is not running; no services are running.and then the empty table. Every other native refusal still fails.ps --jsonnow prints the standard{ok: true, data}envelope that authored native ps already used.datais{backend: "native", status, run, phase, items}. This changes the shape of image-nativeps --json: it used to print the bare object.scripts/accept-native-frontend.pyand its Python test fake now unwrap the envelope. The MCP status tool passes the JSON through unchanged, and crash capture reads only the Docker-pathcomposeProject, so neither needs a change.psalso printsNative project has not been started.fornot_started, matching authored ps.logs --no-follow (image-native and authored)
E_DOCKER_UNAVAILABLE: Native runtime is not running; no service logs are available. Start the native runtime and retry.and exit 1. Before, image-native logs printed a stack, and authored logs printed the misleading "owner/selection changed" message.Top-level error handler (
src/cli/run.ts)ClosedCliError(insrc/lib/cli-result.ts) marks errors whose message is a complete, value-free sentence.NativeRuntimeRequestErrorand the closed refusals innative-project-observenow extend it.ClosedCliErrorandHackCliErrorprint their message only. The stack is added only withHACK_DEBUG=1. Unexpected exceptions still always print their stack, as before.--jsonoutput is unchanged: one error envelope.Other read-only commands checked
open --json(native): reads only the saved routing generation and never calls the runtime, so a stopped runtime does not affect it.doctor(native): turns runtime failures intowarnchecks and does not throw, so no change was needed.hack status(projects --details) andglobal status: no native runtime path.ps: observes through the engine, notinvokeNativeRuntime, so this change does not cover it.Docs:
docs/guides/native-candidate.md,docs/reference/native-authored-commands.mdanddocs/cli.md(HACK_DEBUG).Validation
tests/native-runtime-not-running-cli.test.tsspawns the source CLI withprivateCliEnvand a fake native binary that answers{"code":"runtime_not_running"}(or another code) on stderr with exit 1. It covers: humanps(exit 0, note, table, exactly onegraph inspectcall, no stack frame);ps --json(exact ok envelope);logs web --no-follow, human and--json(exit 1,E_DOCKER_UNAVAILABLE, no stack); a different native code (psexit 1, message printed once, no stack,--jsonerror envelope); andHACK_DEBUG=1(stack present).tests/native-project-observe.test.ts: unit tests for the ps status and logs refusal with injectedinvoke. They also check that other codes and an unstructuredError("runtime_not_running")still throw. The existing not-started CLI test now expects the envelope.tests/native-authored-project-observe.test.ts: unit test for the authored status. Another native code still refuses, and cancellation still wins. Two macOS CLI cases (human and--json) useprivateCliEnv.tests/cli-closed-error-output.test.ts: in-process handler output for closed, coded and unexpected errors,HACK_DEBUG, and--json.NativeRuntimeRequestErrorextendError(2); revert ps JSON to the bare object (2); ignoreHACK_DEBUG(2). With a bare ps JSON reply, the Python acceptance fake fails 14 of 24 tests.tests/integration-ownership.test.tsandtests/cli-spawn-env-isolation.test.ts. Also passing:python3 -m unittest … test_native_frontend_acceptance.py(24),bun run --cwd packages/cli typecheck(0 errors) andbun run --cwd packages/cli check(0 errors; the 34 warnings are in files this PR does not touch). Changed test files passultracite check.Follow-up 0b357fa adds tests for the authored
logs --no-followstopped-runtime path (E_DOCKER_UNAVAILABLE, exit 1, no stack) and the authoredpsdrift recheck. It also fixes a bug the new logs test found: the held saved-read owner turnedruntime_not_runninginto a genericE_LIFECYCLE_FAILED.Gaps
{"code":"runtime_not_running"}, exit 1), whichpackages/runtime-coreemits fromObservedGuest::connectandOwnedGuest::connect_mode.bun run testsuite and hosted CI have not run yet.--json, a closed native refusal still reportsE_UNEXPECTED; this PR does not change its error code.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.