openclaw - ✅(Solved) Fix agent --local --json writes JSON envelope to stderr instead of stdout [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#62440Fetched 2026-04-08 03:04:15
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Timeline (top)
cross-referenced ×1referenced ×1

openclaw agent --local --json --message "..." writes its full JSON result envelope to stderr instead of stdout, leaving stdout empty. The gateway-mode --json path is unaffected. Confirmed against openclaw 2026.3.28.

Root Cause

In the 2026.3.28 dist:

  1. `program-CqrUwYvG.js:115` — when `--json` is detected, the preAction hook calls `routeLogsToStderr()`.
  2. `subsystem-CJEvHE2o.js:188-189` — `routeLogsToStderr()` sets `loggingState.forceConsoleToStderr = true`.
  3. `subsystem-CJEvHE2o.js:434-440` — `writeConsoleLine()` then routes all `console.log` calls (including plain `log` level) to `process.stderr`. Intent: keep noise out of the JSON on stdout.
  4. `subsystem-CJEvHE2o.js:90-105` — the runtime exposes two output paths: `runtime.log()` (which goes through `console.log` → `writeConsoleLine` → now stderr) and `runtime.writeJson()` / `writeStdout()` (which go directly to `process.stdout.write`, bypassing the console interceptor).
  5. `subsystem-CJEvHE2o.js:123-129` — the dispatcher `writeRuntimeJson(runtime, value)` correctly prefers `runtime.writeJson` when available. The gateway-mode agent command (`register.agent-D2kkuHjC.js:86-88`) uses this path correctly.
  6. `auth-profiles-B5ypC5S-.js:215787-215796` — but the local-mode `agentCommand` does not. It calls: ```js if (opts.json) { runtime.log(JSON.stringify(buildOutboundResultEnvelope({...}), null, 2)); ... } ``` which goes through `console.log` → `writeConsoleLine` → stderr (because `forceConsoleToStderr === true`). This is the bug.

Fix Action

Workaround

Local patch that surgically replaces the line: https://github.com/tamakiii/openclaw-workspace/blob/main/patches/openclaw/auth-profiles-fix-local-json-fd.patch (will be live once tamakiii/openclaw-workspace#TBD merges).

PR fix notes

PR #62453: fix: write JSON envelope to stdout in local agent --json mode

Description (problem / solution / changelog)

Summary

Fix for openclaw/openclaw#62440: the local-mode agent --local --json command writes JSON output to stderr instead of stdout. Changed runtime.log(JSON.stringify(buildOutboundResultEnvelope(...), null, 2)) to (runtime as OutputRuntimeEnv).writeJson(buildOutboundResultEnvelope(...)) which writes directly to stdout, matching gateway-mode behavior.

Changes

  • src/agents/command/delivery.ts: replace runtime.log(JSON.stringify(buildOutboundResultEnvelope(...), null, 2)) with (runtime as OutputRuntimeEnv).writeJson(buildOutboundResultEnvelope(...)). Also added OutputRuntimeEnv import.
  • src/commands/agent.delivery.test.ts: update mock to include writeJson and update test assertions to verify writeJson is called correctly.

Testing

  • pnpm test src/commands/agent.delivery.test.ts — 11 tests pass
  • pnpm test src/agents/command/delivery.test.ts — 4 tests pass

Fixes openclaw/openclaw#62440

Changed files

  • src/agents/command/delivery.ts (modified, +6/-10)
  • src/commands/agent.delivery.test.ts (modified, +6/-7)
RAW_BUFFERClick to expand / collapse

Summary

openclaw agent --local --json --message "..." writes its full JSON result envelope to stderr instead of stdout, leaving stdout empty. The gateway-mode --json path is unaffected. Confirmed against openclaw 2026.3.28.

Reproduction

```sh openclaw agent --agent <some-local-capable-agent> --local --json
--message "Health check: print 'pong' and stop." \

/tmp/out.txt 2>/tmp/err.txt echo "exit=$?" wc -l /tmp/out.txt /tmp/err.txt jq . /tmp/err.txt | head ```

Expected: stdout contains the JSON envelope; stderr is empty (or contains only diagnostic logs). Actual: stdout is empty (0 lines); stderr contains a few diagnostic log lines followed by the full JSON envelope.

Root cause

In the 2026.3.28 dist:

  1. `program-CqrUwYvG.js:115` — when `--json` is detected, the preAction hook calls `routeLogsToStderr()`.
  2. `subsystem-CJEvHE2o.js:188-189` — `routeLogsToStderr()` sets `loggingState.forceConsoleToStderr = true`.
  3. `subsystem-CJEvHE2o.js:434-440` — `writeConsoleLine()` then routes all `console.log` calls (including plain `log` level) to `process.stderr`. Intent: keep noise out of the JSON on stdout.
  4. `subsystem-CJEvHE2o.js:90-105` — the runtime exposes two output paths: `runtime.log()` (which goes through `console.log` → `writeConsoleLine` → now stderr) and `runtime.writeJson()` / `writeStdout()` (which go directly to `process.stdout.write`, bypassing the console interceptor).
  5. `subsystem-CJEvHE2o.js:123-129` — the dispatcher `writeRuntimeJson(runtime, value)` correctly prefers `runtime.writeJson` when available. The gateway-mode agent command (`register.agent-D2kkuHjC.js:86-88`) uses this path correctly.
  6. `auth-profiles-B5ypC5S-.js:215787-215796` — but the local-mode `agentCommand` does not. It calls: ```js if (opts.json) { runtime.log(JSON.stringify(buildOutboundResultEnvelope({...}), null, 2)); ... } ``` which goes through `console.log` → `writeConsoleLine` → stderr (because `forceConsoleToStderr === true`). This is the bug.

Suggested fix

One-line change at `auth-profiles-B5ypC5S-.js:215787-215796` (or its TypeScript source equivalent — likely `src/agents/cli/local/agent-command.ts` or similar):

```diff

  • runtime.log(JSON.stringify(buildOutboundResultEnvelope({
  • runtime.writeJson(buildOutboundResultEnvelope({ payloads: normalizedPayloads, meta: result.meta
  • }), null, 2));
  • })); ```

`runtime.writeJson` already uses `process.stdout.write` directly and is what the gateway-mode path uses. Default pretty-print indent is 2. This makes local-mode match gateway-mode behavior.

Impact

Any consumer that scripts `openclaw agent --local --json` and reads stdout sees empty input and assumes the agent failed silently. In our case this hit a `cliBackends.nemoclaw` config that points the gateway back at openclaw itself for containerized execution — every cron run was producing empty payloads despite the agent succeeding.

Workaround

Local patch that surgically replaces the line: https://github.com/tamakiii/openclaw-workspace/blob/main/patches/openclaw/auth-profiles-fix-local-json-fd.patch (will be live once tamakiii/openclaw-workspace#TBD merges).

Environment

  • openclaw `2026.3.28`
  • node `v24.14.0`
  • linux x86_64

extent analysis

TL;DR

The issue can be fixed by changing the runtime.log call to runtime.writeJson in the auth-profiles-B5ypC5S-.js file to correctly output the JSON result to stdout instead of stderr.

Guidance

  • Identify the file auth-profiles-B5ypC5S-.js (or its TypeScript source equivalent) and locate the line runtime.log(JSON.stringify(buildOutboundResultEnvelope({...}));.
  • Replace this line with runtime.writeJson(buildOutboundResultEnvelope({ payloads: normalizedPayloads, meta: result.meta })); to fix the issue.
  • Verify that the JSON result is now correctly output to stdout by running the openclaw agent command with the --local --json options and checking the output.
  • Consider applying the provided workaround patch if a direct code change is not feasible.

Example

- runtime.log(JSON.stringify(buildOutboundResultEnvelope({
+ runtime.writeJson(buildOutboundResultEnvelope({
      payloads: normalizedPayloads,
      meta: result.meta
- }), null, 2));
+ }));

Notes

The fix assumes that the runtime.writeJson function is available and correctly implemented in the auth-profiles-B5ypC5S-.js file or its TypeScript source equivalent.

Recommendation

Apply the suggested fix by changing the runtime.log call to runtime.writeJson to correctly output the JSON result to stdout. This fix is straightforward and directly addresses the identified 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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix agent --local --json writes JSON envelope to stderr instead of stdout [1 pull requests, 1 participants]