Detect dead websocket connections faster after network changes instead of showing `Working` for up to 5 minutes

Open 💬 1 comment Opened Apr 7, 2026 by 0xdeafbeef

What version of Codex CLI is running?

codex-cli 0.118.0

What subscription do you have?

pro

Which model were you using?

_No response_

What platform is your computer?

it is platform independent

What terminal emulator and version are you using (if applicable)?

_No response_

What issue are you seeing?

When the network changes underneath an active Codex session, for example switching VPNs or after resuming from sleep, the TUI can keep showing Working for 5 minutes even though the underlying websocket is effectively dead.

The websocket response stream is considered dead only after stream_idle_timeout_ms, which defaults to 300000 ms (5 minutes).

Relevant code:

  • codex-rs/model-provider-info/src/lib.rs
  • DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300_000
  • DEFAULT_STREAM_MAX_RETRIES = 5
  • DEFAULT_WEBSOCKET_CONNECT_TIMEOUT_MS = 15_000
  • codex-rs/codex-api/src/endpoint/responses_websocket.rs
  • run_websocket_response_stream() waits with tokio::time::timeout(idle_timeout, ws_stream.next())
  • codex-rs/core/src/codex.rs
  • retry UI for websocket reconnects is partially hidden in release builds on the first retry

Because of that, a silent network break can look like a healthy in-progress turn until the 5-minute idle timeout expires.

What steps can reproduce the bug?

Switch vpn, turn wifi on/off/put laptop to sleep and resume.

What is the expected behavior?

Codex should detect dead websocket connections promptly after network changes and either:

  • reconnect within seconds, or
  • clearly show a reconnecting / waiting-for-network state instead of Working

Additional information

Any of these would be an improvement:

  • add proactive websocket heartbeat ping/pong from the client and fail the connection if pong is not received within a short deadline
  • lower the effective websocket idle detection timeout during active turns
  • surface the first websocket reconnect attempt in the TUI instead of hiding it in release builds
  • distinguish between “model is working” and “connection is stalled / reconnecting”

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗