openclaw-matrix-multiaccounts/src/cli
Tom McKenzie 116fbb747f
CLI: fix subcommand registration to work without --help/--version flags (#1683)
## Problem

The clawdbot-gateway systemd service was crash-looping on Linux (Fedora 42,
aarch64) with the error:

    error: unknown command '/usr/bin/node-22'

After ~20 seconds of runtime, the gateway would exit with status 1/FAILURE
and systemd would restart it, repeating the cycle indefinitely (80+ restarts
observed).

## Root Cause Analysis

### Investigation Steps

1. Examined systemd service logs via `journalctl --user -u clawdbot-gateway.service`
2. Found the error appeared consistently after the service had been running
   for 20-30 seconds
3. Added debug logging to trace argv at parseAsync() call
4. Discovered that argv was being passed to Commander.js with the node binary
   and script paths still present: `["/usr/bin/node-22", "/path/to/entry.js", "gateway", "--port", "18789"]`
5. Traced the issue to the lazy subcommand registration logic in runCli()

### The Bug

The lazy-loading logic for subcommands was gated behind `hasHelpOrVersion(parseArgv)`:

```typescript
if (hasHelpOrVersion(parseArgv)) {
  const primary = getPrimaryCommand(parseArgv);
  if (primary) {
    const { registerSubCliByName } = await import("./program/register.subclis.js");
    await registerSubCliByName(program, primary);
  }
}
```

This meant that when running `clawdbot gateway --port 18789` (without --help
or --version), the `gateway` subcommand was never registered before
`program.parseAsync(parseArgv)` was called. Commander.js would then try to
parse the arguments without knowing about the gateway command, leading to
parse errors.

The error message "unknown command '/usr/bin/node-22'" appeared because
Commander was treating the first positional argument as a command name due to
argv not being properly stripped on non-Windows platforms in some code paths.

## The Fix

Remove the `hasHelpOrVersion()` gate and always register the primary
subcommand when one is detected:

```typescript
// Register the primary subcommand if one exists (for lazy-loading)
const primary = getPrimaryCommand(parseArgv);
if (primary) {
  const { registerSubCliByName } = await import("./program/register.subclis.js");
  await registerSubCliByName(program, primary);
}
```

This ensures that subcommands like `gateway` are properly registered before
parsing begins, regardless of what flags are present.

## Environment

- OS: Fedora 42 (Linux 6.15.9-201.fc42.aarch64)
- Arch: aarch64
- Node: /usr/bin/node-22 (symlink to node-22)
- Deployment: systemd user service
- Runtime: Gateway started via `clawdbot gateway --port 18789`

## Why This Should Be Merged

1. **Critical Bug**: The gateway service cannot run reliably on Linux without
   this fix, making it a blocking issue for production deployments via systemd.

2. **Affects All Non-Help Invocations**: Any direct subcommand invocation
   (gateway, channels, etc.) without --help/--version is broken.

3. **Simple & Safe Fix**: The change removes an unnecessary condition that was
   preventing lazy-loading from working correctly. Subcommands should always be
   registered when detected, not just for help/version requests.

4. **No Regression Risk**: The fix maintains the lazy-loading behavior (only
   loads the requested subcommand), just ensures it works in all cases instead
   of only help/version scenarios.

5. **Tested**: Verified that the gateway service now runs stably for extended
   periods (45+ seconds continuous runtime with no crashes) after applying this
   fix.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-25 03:17:02 +00:00
..
browser-cli-actions-input fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
cron-cli fix: clean docker onboarding warnings + preserve agentId casing 2026-01-24 19:07:01 +00:00
daemon-cli fix: stop gateway before uninstall 2026-01-23 07:17:42 +00:00
gateway-cli fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
node-cli fix: harden bluebubbles short ids and fetch wrapper (#1369) (thanks @tyler6204) 2026-01-21 17:09:15 +00:00
nodes-cli fix: honor tools.exec ask/security in approvals 2026-01-24 04:53:44 +00:00
program feat: add system cli 2026-01-24 04:03:07 +00:00
acp-cli.ts feat(acp): add interactive client harness 2026-01-18 08:27:37 +00:00
argv.test.ts refactor: streamline routed cli setup 2026-01-19 00:52:31 +00:00
argv.ts CLI: fix Windows gateway startup 2026-01-23 04:47:01 +00:00
banner.ts fix: clean wrapped banner tagline 2026-01-24 01:26:17 +00:00
browser-cli-actions-input.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
browser-cli-actions-observe.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
browser-cli-debug.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
browser-cli-examples.ts feat: add browser snapshot modes 2026-01-15 03:50:57 +00:00
browser-cli-extension.test.ts chore: prep 2026.1.14 npm release 2026-01-15 07:47:18 +00:00
browser-cli-extension.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
browser-cli-inspect.test.ts fix: add browser snapshot default mode (#1336) 2026-01-21 03:03:10 +00:00
browser-cli-inspect.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
browser-cli-manage.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
browser-cli-serve.ts feat: add Chrome extension browser relay 2026-01-15 04:52:28 +00:00
browser-cli-shared.ts fix(browser-cli): rename --profile to --browser-profile to avoid conflict with global --profile flag 2026-01-06 21:54:46 +01:00
browser-cli-state.cookies-storage.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
browser-cli-state.ts refactor: share cli runtime error handling 2026-01-19 00:52:31 +00:00
browser-cli.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
browser-cli.ts docs: unify cli help examples 2026-01-21 04:48:33 +00:00
channel-auth.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
channel-options.ts feat: add tlon channel plugin 2026-01-24 00:25:39 +00:00
channels-cli.ts feat: add beta googlechat channel 2026-01-24 23:30:45 +00:00
cli-utils.ts refactor: share cli runtime error handling 2026-01-19 00:52:31 +00:00
command-format.ts fix: refactor TUI stream assembly (#1202, thanks @aaronveklabs) 2026-01-20 08:36:54 +00:00
command-options.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
config-cli.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
cron-cli.test.ts test: align agent id normalization 2026-01-24 14:36:31 +00:00
cron-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
daemon-cli.coverage.test.ts chore: run format and fix sandbox browser timeouts 2026-01-16 09:18:58 +00:00
daemon-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
deps.ts feat!: move msteams to plugin 2026-01-16 02:59:43 +00:00
devices-cli.ts feat: tableize device/directory outputs 2026-01-21 04:48:33 +00:00
directory-cli.ts fix: address update cli type import 2026-01-21 06:10:27 +00:00
dns-cli.test.ts fix: align cli output tests and help examples 2026-01-21 05:20:31 +00:00
dns-cli.ts feat: tableize device/directory outputs 2026-01-21 04:48:33 +00:00
docs-cli.ts refactor: share cli runtime error handling 2026-01-19 00:52:31 +00:00
exec-approvals-cli.test.ts fix: add diagnostics cache trace config (#1370) (thanks @parubets) 2026-01-21 10:23:30 +00:00
exec-approvals-cli.ts feat: render approvals tables on write 2026-01-21 11:10:03 +00:00
gateway-cli.coverage.test.ts feat: fold gateway service commands into gateway 2026-01-21 17:45:26 +00:00
gateway-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
gateway-rpc.ts fix: suppress spinner in logs --follow mode 2026-01-22 16:58:42 -08:00
gateway.sigterm.test.ts test: speed up test suite 2026-01-23 02:22:02 +00:00
help-format.ts fix: align cli output tests and help examples 2026-01-21 05:20:31 +00:00
hooks-cli.test.ts feat: support plugin-managed hooks 2026-01-18 05:57:05 +00:00
hooks-cli.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
logs-cli.test.ts refactor: harden log stream writes 2026-01-21 03:03:29 +00:00
logs-cli.ts fix: suppress spinner in logs --follow mode 2026-01-22 16:58:42 -08:00
memory-cli.test.ts refactor: streamline routed cli setup 2026-01-19 00:52:31 +00:00
memory-cli.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
models-cli.test.ts ci: stabilize vitest runs 2026-01-18 06:58:54 +00:00
models-cli.ts feat: add models status auth probes 2026-01-23 19:28:55 +00:00
node-cli.ts fix: resolve ci failures 2026-01-18 08:45:29 +00:00
nodes-camera.test.ts chore: rename project to clawdbot 2026-01-04 14:38:51 +00:00
nodes-camera.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
nodes-canvas.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
nodes-canvas.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
nodes-cli.coverage.test.ts feat: tighten exec allowlist gating 2026-01-21 21:45:50 +00:00
nodes-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
nodes-run.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
nodes-screen.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
nodes-screen.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
outbound-send-deps.ts style: oxfmt format 2026-01-17 05:48:56 +00:00
pairing-cli.test.ts fix: align cli output tests and help examples 2026-01-21 05:20:31 +00:00
pairing-cli.ts feat: tableize device/directory outputs 2026-01-21 04:48:33 +00:00
parse-duration.test.ts feat: add models auth commands 2026-01-09 08:13:04 +01:00
parse-duration.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
parse-timeout.ts refactor: centralize cli timeout parsing 2026-01-09 21:29:52 +01:00
plugin-registry.ts CLI: streamline startup paths and env parsing 2026-01-18 23:10:39 +00:00
plugins-cli.ts fix: put plugin descriptions under source 2026-01-23 04:02:42 +00:00
ports.ts fix: harden port listener detection 2026-01-21 18:52:55 +00:00
profile-utils.ts refactor: normalize cli command hints 2026-01-20 07:43:00 +00:00
profile.test.ts refactor: normalize cli command hints 2026-01-20 07:43:00 +00:00
profile.ts refactor: normalize cli command hints 2026-01-20 07:43:00 +00:00
program.force.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
program.nodes-basic.test.ts feat: filter nodes list/status 2026-01-21 04:39:15 +00:00
program.nodes-media.test.ts fix: enforce strict config validation 2026-01-19 03:39:25 +00:00
program.smoke.test.ts test: dedupe CLI onboard auth cases 2026-01-23 18:34:33 +00:00
program.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
progress.test.ts feat: add memory indexing progress options 2026-01-18 08:30:04 +00:00
progress.ts feat: add memory indexing progress options 2026-01-18 08:30:04 +00:00
prompt.test.ts chore: format to 2-space and bump changelog 2025-11-26 00:53:53 +01:00
prompt.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
route.ts fix: centralize cli command registry 2026-01-19 05:36:09 +00:00
run-main.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
run-main.ts CLI: fix subcommand registration to work without --help/--version flags (#1683) 2026-01-25 03:17:02 +00:00
sandbox-cli.ts docs: unify cli help examples 2026-01-21 04:48:33 +00:00
security-cli.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
skills-cli.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
skills-cli.ts fix: prefer ~ for home paths in output 2026-01-23 03:44:31 +00:00
system-cli.ts feat: add system cli 2026-01-24 04:03:07 +00:00
tagline.ts Update tagline.ts with a nice reference from an old movie 2026-01-18 00:59:43 +00:00
tui-cli.ts docs(cli): add per-command CLI pages 2026-01-15 06:13:10 +00:00
update-cli.test.ts fix: restart gateway after update by default 2026-01-23 11:50:19 +00:00
update-cli.ts fix: restart gateway after update by default 2026-01-23 11:50:19 +00:00
wait.test.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
wait.ts chore: format to 2-space and bump changelog 2025-11-26 00:53:53 +01:00
webhooks-cli.ts feat: unify hooks installs and webhooks 2026-01-17 07:08:04 +00:00