Skip to content

fix(middleware): CLIRuntimeBase silently discards stderr when CLI exits with error #374

@alexey-pelykh

Description

@alexey-pelykh

Problem

When a CLI agent runtime (Claude, Gemini, Codex, OpenCode) exits with an error (e.g., "Not logged in"), the error message printed to stderr is captured into stderrChunks but never logged or included in any event. The agent run completes with an empty done event (text: "", no error), making it impossible to diagnose why the agent produced no output.

Impact

  • Messages sent via Chat UI, Slack, or any channel silently "disappear" with no reply and no error
  • Gateway logs show lifecycle phase=startphase=end in ~1 second with no output in between
  • The chat.send handler's .catch() calls broadcastChatError() but the error message is generic — the actual CLI stderr (e.g., "Not logged in · Please run /login") is lost
  • Debugging requires manually running the CLI binary to discover the real error

Root cause

In src/middleware/cli-runtime-base.ts:

// Line 62: stderr is captured...
const stderrChunks: string[] = [];

// Line 107-109: ...into this array...
diagnosticStream?.on("data", (chunk: Buffer) => {
  stderrChunks.push(chunk.toString());
});

// But stderrChunks is NEVER used after this point.
// The done event at line 231-239 doesn't include stderr.
// No error event is emitted when the process exits non-zero with stderr output.

Expected behavior

When the CLI process exits with a non-zero exit code (or exits with zero but produces no NDJSON output) and stderr contains content, the runtime should:

  1. Emit an error event with the stderr content before the done event
  2. Include stderr in the done event result (e.g., result.error or result.stderr)
  3. Log the stderr content at warn level so it appears in gateway logs

Reproduction

  1. Install RemoteClaw with agents.defaults.runtime: "claude"
  2. Ensure claude CLI is installed but NOT authenticated (claude /login not run)
  3. Send a message via Chat UI
  4. Observe: no reply, no error in logs, message "disappears"
  5. Manually run claude -p "hello" → shows "Not logged in · Please run /login"

Affected file

  • src/middleware/cli-runtime-base.tsexecute() method

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions