Skip to content

[Bug] exec_command intermittently returns empty tool results with implausible wall_time (zero-output completion class) #2472

Description

@lidge-jun

Summary

During a live Codex Desktop session on 2026-08-24 (~14:00-14:40 KST, session 01a03224-c0f5-7a90-87ae-6c17ac691045), exec_command tool calls repeatedly surfaced empty tool results even though the calling agent emitted non-empty result text (text(r.output || JSON.stringify(r)) cannot produce empty output). Identical commands succeeded minutes later. The local shell itself is healthy — post-incident probes of plain echo, tty mode, stderr-only + exit codes all pass.

This looks like the same zero-output completion class as #2423 (OpenRouter Ox Alpha returns HTTP 200 but Codex App receives an empty completion): the turn's tool-result content is lost upstream/in-transit and Codex renders it as an empty result instead of a typed failure.

Evidence

  1. Empty-but-successful results: multiple consecutive exec_command calls returned no visible content; rerunning the exact same commands immediately after returned normal output. One probe used text(r.output || JSON.stringify(result)) — the fallback guarantees non-empty text, yet nothing rendered, so the loss is downstream of the agent (stream/transport), not the shell.

  2. Implausible wall_time_seconds telemetry on results that did arrive:

    • echo err-only >&2; exit 3 → exit 3, correct stderr, but wall_time_seconds: 0.000002875 (a real process spawn takes >= 5ms).
    • sleep 1; echo done → reported 0.85s vs JS-measured 1067ms (plausible), so timing is only broken on some terminal paths (observed on stderr-only terminals).
    • Several empty-output results also carried microsecond-scale wall_time_seconds, consistent with a response object assembled without the command ever running through the normal terminal path.
  3. Running bridge predates the zero-output mitigation: the serving process (PID 922, bun src/cli/index.ts start --port 10100) started 2026-08-23 22:59:12 KST, before:

    So the live process does not include fix(combos): fail over zero-output stream failures, recording each terminal once #2449's zero-output failover/preflight; a silent zero-output stream surfaces to the client as empty success instead of failing over or erroring.

Suspected root cause

Two distinct defects:

  1. Transport/upstream (primary): a provider turn completes with zero decoded content (HTTP 200, no frames or frame-loss) and the bridge treats it as a clean terminal. The client sees an empty tool result with no error. Same family as OpenRouter Ox Alpha returns HTTP 200 but Codex App receives an empty completion without retry #2423 and the silent/heartbeat-only stall class addressed by 994e5ba (T04) — but here the stream terminates cleanly-with-zero-output rather than hanging past the watchdog.
  2. Telemetry (secondary): wall_time_seconds is captured at the wrong point for at least the stderr-only terminal path (and appears on empty results), producing microsecond values that make incidents harder to triage.

Suggested next steps

Environment

  • OpenCodex dev @ 438b9cc (running process older than HEAD)
  • macOS arm64, Codex Desktop app-server + code-mode host
  • Provider route in use during incident: ocx/xai default with stealth/ox-alpha model

Metadata

Metadata

Assignees

No one assigned

    Labels

    toolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions