Skip to content

fix(runtime): surface catalog spawn failures and stop misreporting resolved executables - #215

Merged
eddiearc merged 3 commits into
eddiearc:mainfrom
itswl:fix/runtime-catalog-spawn-diagnostics
Sep 13, 2026
Merged

eddiearc merged 3 commits into
eddiearc:mainfrom
itswl:fix/runtime-catalog-spawn-diagnostics

Conversation

@itswl

@itswl itswl commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

What

The runtime model-catalog probes (claude / codex) discard the underlying spawn error (child.on("error", () => finish(new Error("... model catalog command failed")))), so the real cause is lost. And classifyRuntimePrerequisite's ENOENT branch reports not installed even when the caller already resolved an absolute, existing executable — a launch-environment failure (bad working directory, interpreter, permissions) then reads as "reinstall the runtime". The pi runtime already surfaces the spawn errno through PiRpcClient (Pi RPC process failed: ... ENOENT), but its resolved-executable case was misclassified the same way.

Change

  • src/runtime/claude-model-catalog.ts / src/runtime/codex-model-catalog.ts: include the underlying error.message (carries the errno, e.g. spawn <path> ENOENT) in the wrapped failure.
  • src/runtime/runtime-readiness.ts (classifyRuntimePrerequisite): keep the not installed diagnosis only when no executable was resolved or the resolved file no longer exists; a still-existing resolved executable preserves the raw spawn reason and gets a nextAction pointing at the launch environment (working directory, interpreter, permissions).
  • Tests: spawn-failure coverage in test/unit/runtime/{claude,codex}-model-catalog.test.mjs and classification coverage for all three runtimes — including pi's Pi RPC process failed: ... ENOENT shape — in test/unit/runtime/runtime-readiness.test.mjs.

Validation

  • bun run build
  • bun run typecheck
  • bun test test/unit/runtime/claude-model-catalog.test.mjs test/unit/runtime/codex-model-catalog.test.mjs test/unit/runtime/runtime-readiness.test.mjs → 28 pass / 0 fail
  • bun run test:unit → 882 pass / 16 skip / 2 fail. Both failures (shared tmux session lists windows by recorded owner, three-Agent live acceptance is opt-in, hermetic by default, and fixture-verifiable) reproduce identically on unmodified main in this environment (tmux is not installed here) and are unrelated to this change.

Fixes #213

🤖 Generated with Claude Code

…solved executables

The claude/codex model-catalog probes replaced the underlying spawn error
with a fixed "command failed" message, so ENOENT and friends never
reached the readiness classifier. And classifyRuntimePrerequisite's
ENOENT branch claimed "<runtime> is not installed" even when the caller
had already resolved an existing absolute executable — a launch
environment failure (working directory, interpreter, permissions) then
read as a missing install.

Carry the underlying error message through the probes and keep the raw
spawn reason when the resolved executable still exists on disk.

Co-Authored-By: Claude Code <noreply@anthropic.com>

@eddiearc eddiearc left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MERGE-WITH-NITS(Fable 5.1 审合)

catalog 带上底层 spawn errno;classify 在「已解析且文件仍在」时不再误报 not installed,改指 launch environment。三端 runtime 分类单测到位,与 #224 的 raw error 组合关系清楚。风险低。

#214 同改 runtime-readiness 测末尾会有琐碎冲突;本 PR 可先合。缺 version bump。

@eddiearc
eddiearc merged commit 0404097 into eddiearc:main Sep 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: runtime 目录探测吞掉 spawn 失败的真实 errno;已解析的 executable 仍被报成 not installed

2 participants