openclaw - ✅(Solved) Fix [Bug]: Parent command --help shows no subcommands in 2026.4.8 [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#63353Fetched 2026-04-09 07:54:53
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
cross-referenced ×1

Running openclaw <command> --help for any command with subcommands (marked with * in root help) shows no subcommands. The root openclaw --help works correctly because it uses precomputed metadata, but parent commands like config, models, gateway, cron, etc. all show an empty help with no subcommands listed.

The subcommands themselves still work fine (e.g. openclaw config get executes correctly), they just don't appear in help output.

Root Cause

Lazy command registration in register-command-groups-QnmPUiHt.js registers subcommands inside the .action() handler, which Commander.js does not invoke for --help. The shouldRegisterPrimaryCommandOnly() function in command-registration-policy-DRFI5HGH.js detects --help and avoids eager registration of the specific command, so subcommands are never populated before help renders.

Root help works because it reads from precomputed cli-startup-metadata.json.

PR fix notes

PR #63512: fix(CLI): disable help on lazy placeholders so --help triggers lazy-load reparse

Description (problem / solution / changelog)

Summary

  • Lazy-loaded CLI commands (config, models, gateway, cron, channels, agents, etc.) with subcommands showed an empty help when invoked with --help, because Commander.js does not call the .action() handler for --help, so subcommands were never registered before help rendered.
  • Adding placeholder.helpOption(false) to the placeholder command removes the --help flag intercept on the placeholder, causing Commander to fall through and re-trigger the lazy-load action handler which then registers real subcommands and re-parses --help against the fully loaded command tree.
  • Root help continued to work because it reads from precomputed cli-startup-metadata.json.
  • Includes 3 unit tests covering help bypass, allowUnknownOption/allowExcessArguments flags, and register invocation on action.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #63353
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: registerLazyCommand creates a placeholder sub-command with Commander's default --help option enabled. When the user runs openclaw <command> --help, Commander intercepts --help on the placeholder and renders help before the .action() handler fires, so subcommands are never registered and help appears empty.
  • Missing detection / guardrail: No test verifying that --help on a lazy placeholder triggers the full command registration path rather than showing empty help.
  • Contributing context: The lazy-registration pattern was introduced to speed up CLI startup; the shouldRegisterPrimaryCommandOnly() function correctly skips eager registration for help, but the placeholder itself was still capturing --help.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
  • Target test or file: src/cli/program/register-lazy-command.test.ts
  • Scenario the test should lock in: A lazy placeholder command with --help does not show empty help; instead help is deferred to the real action handler after lazy registration.
  • Why this is the smallest reliable guardrail: The bug is in Commander.js option handling on the placeholder, and a unit test on registerLazyCommand directly asserts helpOption(false) and that no --help option remains on the placeholder — the minimal contract that prevents the regression.

User-visible / Behavior Changes

  • openclaw <command> --help now correctly lists available subcommands for all lazy-loaded command groups (config, models, gateway, cron, channels, agents, etc.). Previously showed empty help.

Diagram

Before:
openclaw config --help → Commander intercepts --help on placeholder → shows empty help (no subcommands)

After:
openclaw config --help → placeholder has helpOption(false) → --help not intercepted → action handler fires → subcommands registered → re-parse shows full help with subcommands

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS (darwin)
  • OpenClaw 2026.4.8

Steps

  1. Run openclaw config --help
  2. Observe: only "Usage: openclaw config [options]" with no subcommands listed
  3. After fix: openclaw config --help shows get, set, unset, file, validate subcommands

Expected

All subcommands listed under parent command help.

Actual (before fix)

Empty help — no subcommands shown.

Evidence

  • Failing test/log before + passing after
    • New test in register-lazy-command.test.ts asserts placeholder._helpOption === null and placeholder.options.find(opt => opt.long === "--help") === undefined, which would have caught this bug.

Human Verification (required)

  • Verified scenarios: Placeholder .helpOption(false) correctly disables help intercept; --help falls through to action handler; subcommands appear in help output.
  • Edge cases checked: allowUnknownOption and allowExcessArguments flags still set correctly; register callback still invoked on action.
  • What I did not verify: Full CLI integration test with all command groups (covered by existing e2e tests).

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: Commands that intentionally relied on placeholder --help showing only placeholder-level help (no subcommands) will now show full help.
    • Mitigation: This is the desired behavior and matches pre-2026.4.8 behavior. No known use case for wanting empty help.

Changed files

  • src/cli/program/register-lazy-command.test.ts (added, +103/-0)
  • src/cli/program/register-lazy-command.ts (modified, +1/-0)

Code Example

openclaw --version
# OpenClaw 2026.4.8 (9ece252)

openclaw config --help
# Shows: Usage: openclaw config [options]
# Missing: get, set, unset, file, validate subcommands

openclaw models --help
# Shows: Usage: openclaw models [options]
# Missing: all subcommands
RAW_BUFFERClick to expand / collapse

Description

Running openclaw <command> --help for any command with subcommands (marked with * in root help) shows no subcommands. The root openclaw --help works correctly because it uses precomputed metadata, but parent commands like config, models, gateway, cron, etc. all show an empty help with no subcommands listed.

The subcommands themselves still work fine (e.g. openclaw config get executes correctly), they just don't appear in help output.

Steps to reproduce

openclaw --version
# OpenClaw 2026.4.8 (9ece252)

openclaw config --help
# Shows: Usage: openclaw config [options]
# Missing: get, set, unset, file, validate subcommands

openclaw models --help
# Shows: Usage: openclaw models [options]
# Missing: all subcommands

Affects every command with subcommands — config, gateway, cron, models, channels, agents, etc.

Root cause

Lazy command registration in register-command-groups-QnmPUiHt.js registers subcommands inside the .action() handler, which Commander.js does not invoke for --help. The shouldRegisterPrimaryCommandOnly() function in command-registration-policy-DRFI5HGH.js detects --help and avoids eager registration of the specific command, so subcommands are never populated before help renders.

Root help works because it reads from precomputed cli-startup-metadata.json.

Expected behavior

openclaw <command> --help should list all available subcommands, as it did in 2026.4.5.

Environment

  • OpenClaw 2026.4.8 (9ece252)
  • macOS (darwin), Homebrew global npm install
  • Node v25.8.1

Related

  • #59449 — similar but different (subcommand help showing parent help)

extent analysis

TL;DR

Modify the register-command-groups-QnmPUiHt.js file to register subcommands outside of the .action() handler to ensure they are populated before help is rendered.

Guidance

  • Review the register-command-groups-QnmPUiHt.js file to identify where subcommands are registered inside the .action() handler and consider moving this registration to a point before the help is rendered.
  • Investigate the shouldRegisterPrimaryCommandOnly() function in command-registration-policy-DRFI5HGH.js to understand how it detects --help and avoids eager registration, and consider adjusting this logic to accommodate subcommand registration.
  • Verify that the precomputed cli-startup-metadata.json used by the root help command can be utilized or updated to include subcommands for other commands.
  • Test the changes by running openclaw <command> --help for various commands with subcommands to ensure they are now listed correctly.

Example

No specific code example is provided due to the complexity of the issue and the need for a detailed review of the affected files.

Notes

The solution may require a deeper understanding of how Commander.js handles subcommands and help rendering, as well as the specific implementation details of OpenClaw's command registration logic.

Recommendation

Apply a workaround by modifying the register-command-groups-QnmPUiHt.js file to register subcommands outside of the .action() handler, as this directly addresses the identified root cause of the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

openclaw <command> --help should list all available subcommands, as it did in 2026.4.5.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING