#12308: fix(cli): redirect log output to stderr during completion script generation
cli
size: S
trusted-contributor
experienced-contributor
Cluster:
CLI Enhancements and Fixes
## Summary
Fixes #12241
When running `source <(openclaw completion --shell zsh)`, ANSI-colored subsystem log messages (e.g. `[plugins] Loaded 3 plugins`) leak onto stdout and corrupt the completion script. Zsh then fails with `bad pattern` errors when it encounters the escape codes.
**Root cause:** `enableConsoleCapture()` patches `console.log`, but subsystem loggers write colored messages via `writeConsoleLine()` which uses `rawConsole.log` (the original, unpatched `console.log`). These messages bypass the capture layer and go directly to stdout.
**Fix (two parts):**
1. **`run-main.ts`**: Detect the `completion` command early and call `routeLogsToStderr()` right after `enableConsoleCapture()`. This redirects both the patched console and `writeConsoleLine()` output to stderr, keeping stdout clean for the script.
2. **`completion-cli.ts`**: Switch from `console.log(script)` to `process.stdout.write(script)`. Since `routeLogsToStderr()` makes the patched `console.log` redirect to stderr, the completion script itself must use `process.stdout.write()` to stay on stdout. Also adds an async EPIPE/EIO handler for graceful broken-pipe handling (e.g. when piped to `head`), re-throwing non-transient errors.
## Test plan
- [x] New test: subsystem logger does not write to stdout when `routeLogsToStderr` is active
- [x] New test: `process.stdout.write` bypasses patched console when `forceConsoleToStderr` is active
- [x] New test: `console.log` sends to stderr when `routeLogsToStderr` is active (demonstrates need for `process.stdout.write`)
- [x] All 3 new tests fail before fix, pass after (TDD)
- [x] `pnpm build && pnpm check` passes
- [x] Existing tests unaffected (13/13 pass in completion test suite)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes `openclaw completion` output corruption by ensuring all subsystem/console logging is redirected to stderr during completion script generation, while the completion script itself is written directly to stdout.
Key changes:
- `src/cli/run-main.ts`: detects the `completion` primary command early and calls `routeLogsToStderr()` immediately after `enableConsoleCapture()` so both patched `console.*` and subsystem `writeConsoleLine()` output go to stderr.
- `src/cli/completion-cli.ts`: switches from `console.log(script)` to `process.stdout.write()` to keep the actual completion script on stdout even when console output is forced to stderr, and handles broken-pipe errors (EPIPE/EIO) gracefully via the write callback.
- `src/cli/completion-cli.stdout.test.ts`: adds tests that assert directly on `process.stdout.write`/`process.stderr.write` and `loggingState.rawConsole.error` to validate no stdout leakage and correct routing when `routeLogsToStderr()` is active.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Changes are narrowly scoped to completion-script generation, redirecting logs to stderr and writing the script via stdout, with targeted tests validating the intended stdout/stderr behavior and correct handling of broken-pipe errors.
- No files require special attention
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22488: fix(cli): redirect plugin logs to stderr during completion
by pierreeurope · 2026-02-21
90.6%
#13840: perf(cli): skip plugin loading during completion generation
by lailoo · 2026-02-11
82.7%
#9148: Fix: Speed up shell completion generation from ~4.6s to <200ms
by vishaltandale00 · 2026-02-04
81.6%
#17680: perf(cli): skip plugin loading during completion generation
by mcrolly · 2026-02-16
81.6%
#6382: fix(cli): silence Powerlevel10k Zsh warning from completion script
by dungngo4520 · 2026-02-01
80.9%
#16908: fix(cli): clean stale shell completion profile entries on uninstall...
by lorstyang · 2026-02-15
80.6%
#6694: fix: Cache completion install
by s0up4200 · 2026-02-01
80.0%
#8617: fix: truncate large console payloads before writing to file log
by dbottme · 2026-02-04
79.9%
#17325: fix(completion): avoid zsh compdef error when compinit is not initi...
by ephelia-ai · 2026-02-15
79.6%
#17962: fix(cli): speed up completion plugin loading
by forketyfork · 2026-02-16
78.9%