#3338·nanoclaw

Codex WebSocket idle retry is hidden until NanoClaw’s 10-minute turn timeout

Author: ionescu77Created Aug 18, 2026Updated Sep 15, 2026

Summary

A simple Telegram request can remain silent for ten minutes when the Codex Responses WebSocket stalls.

Codex CLI detects its own five-minute WebSocket idle timeout and retries internally, but codex app-server does not surface that failure to NanoClaw. NanoClaw therefore waits until its fixed ten-minute TURN_TIMEOUT_MS expires.

Environment

  • NanoClaw v2
  • Provider: codex
  • Codex CLI: 0.138.0
  • Model: gpt-5.4, reasoning effort high
  • Authentication: API key through OneCLI
  • Channel: Telegram
  • Linux/systemd
  • Upstream checked: main at 53ea1e8b, providers at efc8eff4

Reproduction observed

  1. Send a simple Telegram request requiring a small workspace edit.
  2. NanoClaw starts/resumes the Codex thread successfully.
  3. Codex sends response.create successfully.
  4. No WebSocket response events arrive for five minutes.
  5. Codex logs:
    stream error: idle timeout waiting for websocket
    stream disconnected - retrying sampling request (1/5 ...)
  1. The retry remains inside Codex CLI and is not emitted as an app-server error.
  2. At ten minutes, NanoClaw emits:
     Error: Turn timed out after 600000ms

No model output or tool call occurred before the timeout.

Follow-up Telegram messages sent while the turn was stalled were steered into the same active turn, making the bot appear completely stuck.

Relevant implementation

container/agent-runner/src/providers/codex.ts uses:

const TURN_TIMEOUT_MS = 10 * 60 * 1000;

The timeout is fixed wall-clock time. It is not aware of Codex’s internal WebSocket idle timeout or retry state. Timeout errors are also currently emitted with retryable: false.

Expected behavior

NanoClaw should not remain silent for ten minutes after Codex’s transport has already stalled.

Ideally it should:

  1. Detect prolonged app-server turn inactivity.
  2. Interrupt the stalled Codex turn.
  3. Notify the messaging channel promptly.
  4. Replay automatically only when no assistant output, tool call, or other side effect occurred.
  5. Queue follow-up messages separately instead of steering them into a stalled turn.

At minimum, the error should explain that the Codex transport stalled and that the original request may need retrying.

Additional context

This appears related to OpenAI Codex issue #19821, where Responses WebSocket failures consume the stream retry budget before HTTP fallback:

https://github.com/openai/codex/issues/19821

A possible short-term mitigation may be disabling WebSocket transport for Codex, but NanoClaw should still have its own activity watchdog and safe recovery behavior.