You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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.
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.
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:
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.
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.
Add a regression test: a stream that ends turnEnded with zero decoded output must yield a typed error (or trigger combo failover), never a silent empty tool result.
Fix wall-time capture so every terminal path reports monotonic elapsed time of the actual child process.
Consider extending the T04/T05 contract: clean-terminal-with-zero-output deserves the same typed-failure treatment as unknown-exec frames (b513a91).
Environment
OpenCodex dev @ 438b9cc (running process older than HEAD)
Summary
During a live Codex Desktop session on 2026-08-24 (~14:00-14:40 KST, session 01a03224-c0f5-7a90-87ae-6c17ac691045),
exec_commandtool 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
Empty-but-successful results: multiple consecutive
exec_commandcalls returned no visible content; rerunning the exact same commands immediately after returned normal output. One probe usedtext(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.Implausible
wall_time_secondstelemetry on results that did arrive:echo err-only >&2; exit 3→ exit 3, correct stderr, butwall_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).wall_time_seconds, consistent with a response object assembled without the command ever running through the normal terminal path.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:
wall_time_secondsis 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
turnEndedwith zero decoded output must yield a typed error (or trigger combo failover), never a silent empty tool result.Environment