fix(cli): report oclif parse errors without a raw stack trace - #8125
Conversation
The direct command-id route recognized parse errors by class name, so an invalid enum flag or argument value escaped as an unhandled rejection: a Node stack trace, an error-property dump, and exit 1 instead of the declared 2. Recognize the shape every oclif parse error carries so the route prints one actionable line and exits with the parser code. Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
📝 WalkthroughWalkthroughThe CLI now recognizes oclif parse errors by structural properties. Tests cover invalid enum flags and arguments, formatted exit code 2 responses, removal of parser details, and rethrowing unrelated command failures. ChangesCLI parse error handling
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit de827bf in the TypeScript / code-coverage/cliThe overall coverage in commit de827bf in the Updated |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/cli/oclif-parse-errors.test.ts`:
- Around line 22-26: Update both CLI parse-error tests around the
reasoning-effort validation assertions to explicitly verify the required help
hint is present in r.out, in addition to the validation message and clean
parse-failure checks. Use the observable command output and preserve the
existing exit-code assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 307e3f6c-8242-4cfb-97c4-975d4c4b9abd
📒 Files selected for processing (3)
src/lib/cli/oclif-runner.test.tssrc/lib/cli/oclif-runner.tstest/cli/oclif-parse-errors.test.ts
| expect(r.code).toBe(PARSER_EXIT_CODE); | ||
| expect(r.out).toContain( | ||
| "Expected --reasoning-effort=ultra to be one of: low, medium, high, default", | ||
| ); | ||
| expectCleanParseFailure(r.out); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the help hint in both CLI tests.
Issue #8123 requires the validation message and the help hint. These assertions pass if output omits the help hint.
Proposed test change
expect(r.out).toContain(
"Expected --reasoning-effort=ultra to be one of: low, medium, high, default",
);
+ expect(r.out).toContain("See more help with --help");
expectCleanParseFailure(r.out);
@@
expect(r.code).toBe(PARSER_EXIT_CODE);
expect(r.out).toContain("Expected powershell to be one of: bash, zsh, fish");
+ expect(r.out).toContain("See more help with --help");
expectCleanParseFailure(r.out);As per path instructions, “Prefer observable outcomes through the public boundary.”
Also applies to: 32-34
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/cli/oclif-parse-errors.test.ts` around lines 22 - 26, Update both CLI
parse-error tests around the reasoning-effort validation assertions to
explicitly verify the required help hint is present in r.out, in addition to the
validation message and clean parse-failure checks. Use the observable command
output and preserve the existing exit-code assertions.
Source: Path instructions
PR Review Advisor — InformationalAdvisor assessment: Informational / low confidence Model lanes
Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate. 1 semantic terminology decisionTerminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.
E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: None This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
apurvvkumaria
left a comment
There was a problem hiding this comment.
Reviewed exact head de827bf. The structural oclif parse-error predicate is narrowly gated by exit metadata, an own parse field, and boolean help metadata, with unit and CLI regression coverage plus a negative command-failure case. I found no blocking defect. The failing installer test is in unrelated station-pair preparation coverage, while the affected CLI suites passed; automated advisor output reports no blocker.
<!-- markdownlint-disable MD041 --> ## Summary Prepares the canonical v0.0.102 release documentation from the current release-labeled scope. The change adds a dated changelog for all 38 user-facing shipping PRs and corrects the OpenClaw agent command reference for the behavior delivered by #8191. ## Changes - Add `docs/changelog/2026-08-04.mdx` with the v0.0.102 release summary, detailed behavior changes, support boundaries, security evidence links, and links to durable documentation. - Update `docs/reference/commands.mdx` to describe non-JSON OpenClaw output capture, its combined limit, marker handling, stream suppression, recovery guidance, and exit behavior. - [#8167](#8167) -> `docs/changelog/2026-08-04.mdx`: Records authenticated attachment of operator-managed llama.cpp servers. - [#8129](#8129) -> `docs/changelog/2026-08-04.mdx`: Records the Experimental managed vLLM profile for two DGX Spark systems. - [#7983](#7983) -> `docs/changelog/2026-08-04.mdx`: Records qualification of the May 2026 GB300WS factory image. - [#8207](#8207) -> `docs/changelog/2026-08-04.mdx`: Records the qualified DGX Station driver transaction. - [#8208](#8208) -> `docs/changelog/2026-08-04.mdx`: Records mode-bound Express resume state. - [#8158](#8158) -> `docs/changelog/2026-08-04.mdx`: Records recovery of host-global dual-Station runtime ownership. - [#8145](#8145) -> `docs/changelog/2026-08-04.mdx`: Records Windows-host Ollama validation from Docker Desktop's network context. - [#8190](#8190) -> `docs/changelog/2026-08-04.mdx`: Records HTTP model pulls when WSL has no local Ollama executable. - [#8195](#8195) -> `docs/changelog/2026-08-04.mdx`: Records reuse of a healthy installer-managed CLI. - [#8053](#8053) -> `docs/changelog/2026-08-04.mdx`: Records early rejection of incompatible OpenShell gateway versions. - [#8098](#8098) -> `docs/changelog/2026-08-04.mdx`: Records the bounded package-service-to-standalone gateway recovery transition. - [#8216](#8216) -> `docs/changelog/2026-08-04.mdx`: Records the final dashboard port selected during multi-sandbox onboarding. - [#8146](#8146) -> `docs/changelog/2026-08-04.mdx`: Records managed startup-state restoration for stopped sandboxes. - [#8092](#8092) -> `docs/changelog/2026-08-04.mdx`: Records gateway watchdog recovery for classified not-serving states. - [#8182](#8182) -> `docs/changelog/2026-08-04.mdx`: Records consistent managed-recovery wait configuration. - [#8040](#8040) -> `docs/changelog/2026-08-04.mdx`: Records Docker sandbox rollback authority through late validation. - [#8130](#8130) -> `docs/changelog/2026-08-04.mdx`: Records bounded Shields deadline recovery and durable containment. - [#8086](#8086) -> `docs/changelog/2026-08-04.mdx`: Records repair of narrowly validated permission-only configuration drift. - [#8122](#8122) -> `docs/changelog/2026-08-04.mdx`: Records prompt failure and guidance for corrupt transition locks. - [#8124](#8124) -> `docs/changelog/2026-08-04.mdx`: Records policy restoration flags, previews, and target revalidation. - [#7886](#7886) -> `docs/changelog/2026-08-04.mdx`: Records explicit destruction after pre-delete Shields hardening failures while preserving recovery authority. - [#7901](#7901) -> `docs/changelog/2026-08-04.mdx`: Records multi-port uninstall behavior and shared-resource preservation. - [#7984](#7984) -> `docs/changelog/2026-08-04.mdx`: Records one classified transient remote MCP startup retry. - [#7954](#7954) -> `docs/changelog/2026-08-04.mdx`: Records bounded hosted-inference probe replies. - [#7574](#7574) -> `docs/changelog/2026-08-04.mdx`: Records preservation of validated reasoning capabilities through onboarding. - [#8089](#8089) -> `docs/changelog/2026-08-04.mdx`: Records proxy routing for Hermes WhatsApp pairing and media traffic. - [#7682](#7682) -> `docs/changelog/2026-08-04.mdx`: Records native Hermes session deletion and identifier validation. - [#8150](#8150) -> `docs/changelog/2026-08-04.mdx`: Records corporate CA trust for LangChain Deep Agents Code image builds. - [#8156](#8156) -> `docs/changelog/2026-08-04.mdx`: Records reviewed managed runtime dependency remediation. - [#8180](#8180) -> `docs/changelog/2026-08-04.mdx`: Records reviewed MCP discovery runtime dependency updates. - [#8196](#8196) -> `docs/changelog/2026-08-04.mdx`: Records private npm dependency remediation across managed images. - [#8203](#8203) -> `docs/changelog/2026-08-04.mdx`: Records reviewed Hermes and LangChain Deep Agents Code Python dependency updates. - [#8125](#8125) -> `docs/changelog/2026-08-04.mdx`: Records bounded diagnostics for invalid enumerated CLI values. - [#8193](#8193) -> `docs/changelog/2026-08-04.mdx`: Records bounded diagnostics for unresolved sandbox base images. - [#8118](#8118) -> `docs/changelog/2026-08-04.mdx`: Records bounded diagnostics for changed gateway authority. - [#8191](#8191) -> `docs/changelog/2026-08-04.mdx`, `docs/reference/commands.mdx`: Records output capture, marker handling, recovery guidance, and exit behavior for non-JSON OpenClaw agent commands. - [#8187](#8187) -> `docs/changelog/2026-08-04.mdx`: Records the aligned interactive-installation start across supported agents. - [#8153](#8153) -> `docs/changelog/2026-08-04.mdx`: Records current product capabilities and support boundaries. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: This documentation-only release preparation does not change executable behavior. Existing changelog and published-route tests pass. - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: Independently reviewed `docs/changelog/2026-08-04.mdx` and `docs/reference/commands.mdx` at commit `b89913780`. All 38 user-facing v0.0.102 PRs are represented, #8191 behavior matches the implementation, and the writing rules, documentation style, controlled terminology, route structure, and skip policy pass review. Targeted tests pass 36/36 and the documentation build completes with 0 errors. - Agent: Codex Desktop independent documentation writer <!-- docs-review-head-sha: b899137 --> <!-- docs-review-agents-blob-sha: 3dd7c24 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable - Station profile/scenario: Not applicable - Result: Not applicable - Supporting evidence: Not applicable ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run validate:pr` passed after refreshing `origin/main` when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `npx vitest run --project integration test/changelog-docs.test.ts test/check-docs-published-routes.test.ts` passed 36/36. - [x] Applicable broad gate passed — not applicable to documentation-only changes; `npm run docs` completed successfully with 0 errors. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — completed with 0 errors and 2 existing Fern warnings. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [x] New doc pages include SPDX header and frontmatter (new pages only) — the native dated changelog uses the required parser-safe MDX SPDX comment and intentionally has no frontmatter. --- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Added release notes for v0.0.102, covering authentication, hardware setup, WSL, installer recovery, sandbox resilience, policy management, inference reliability, CLI improvements, and unified quickstarts. - Updated command documentation to explain how non-JSON agent output is collected, replayed, and reported. - **Bug Fixes** - Improved command-output recovery guidance when output exceeds limits or contains unsupported fallback markers. - Preserved accurate command exit-status reporting after output processing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Summary
Passing a value outside a flag's or argument's declared enum crashed the CLI instead of reporting the mistake. oclif's parse error escaped as an unhandled rejection, so the user got a Node stack trace, an error-property dump, and the Node version banner, and the process exited 1 instead of the declared parser code 2. The actionable line was present but buried mid-trace. Those commands now print that line on its own and exit 2.
Related Issue
Fixes #8123
Changes
src/lib/cli/oclif-runner.ts:runOclifCommandByIdmaps oclif errors to exit codes by hand rather than delegating to oclif'shandle(), and it recognized parse errors from a list of class names. That list covered four of oclif's sevenCLIParseErrorsubclasses, soFlagInvalidOptionErrorandArgInvalidOptionErrorfell through to the final rethrow and out ofdispatchCli(), which has no rejection handler. AddedhasOclifParseErrorShape, which matches on the three markers theCLIParseErrorbase class gives every subclass: a numericoclif.exit, an ownparseproperty, and a booleanshowHelp. Matching the shape rather than the name covers the subclasses added since the list was written and any added later.src/lib/cli/oclif-runner.ts: the existing name list stays as written and is OR'd with the new check, so no error that already reached the parse branch changes route. Recognized errors keep using the existingexit(exitCode ?? 1)line, which yields 2 for a parse error with no further change.internalandsandboxnamespaces go throughrunOclifArgv, which does call oclif'shandle()and already printed these cleanly, which is whynemoclaw <sandbox-name> inference setbehaved while the globalnemoclaw inference setcrashed.src/lib/cli/oclif-runner.test.tscovers an invalid enum flag value, an invalid enum argument value, a parse error whose class name is unknown but whose shape matches, and a command failure carrying an unrelatedparseproperty that must still rethrow.test/cli/oclif-parse-errors.test.tsruns the real CLI for both user-visible commands and asserts the exit code, the actionable line, and the absence of stack frames,@oclif/corepaths, and the Node version banner.Type of Change
Quality Gates
docs/inference/configure-model-capabilities.mdxdocuments which--reasoning-effortvalues are accepted, anddocs/reference/commands.mdxlists the commands and flags. No page documents the previous exit code, the stack trace, or the error text for a rejected value.Documentation Writer Review
blockedDGX Station Hardware Evidence
Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run validate:prpassed after refreshingorigin/mainwhen hooks were skipped or unavailablenpx vitest run --project cli src/lib/cli/ --project integration test/cli/dispatch-basics.test.ts test/cli/onboard-compatibility.test.ts test/cli/oclif-parse-errors.test.ts— 13 files, 136 tests passed. Withsrc/lib/cli/oclif-runner.tsreverted anddistrebuilt, the 5 new assertions fail and the other 15 in those two files still pass, which pins both the recognition change and the exit code. Before the fix,nemoclaw inference set --reasoning-effort ultraandnemoclaw completion powershellreproduced the reported trace and exit 1; after it, both print one line plus the help hint and exit 2, whilenemoclaw onboard --non-interactivis unchanged.npm run typecheck:cliclean.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docsbuilds without warnings (doc changes only)Signed-off-by: Tinson Lai tinsonl@nvidia.com
Summary by CodeRabbit
Bug Fixes
Tests