Codex retry label counts past its max ("Retrying provider (34/5)") once Codex switches to "waiting for network"#30791

opened6d agobyGgrenmango51

What happened

A Codex turn kept showing "Retrying provider (N/5)" with N climbing well past 5. The screenshot shows Retrying provider (34/5) after 32 minutes, with detail Connection failed: error sending request. The label suggests T3 is ignoring a 5-attempt limit. In fact Codex itself never gives up in this phase: only the label is wrong.

Underlying cause of the failures on this machine: Codex was configured with a custom model_provider whose base_url is a local proxy (http://127.0.0.1:8317/v1), and that proxy wasn't running.

Diagnosis

Codex 0.166 (app-server) reports stream retries as error notifications with willRetry: true:

  1. Reconnecting... 2/5 … Reconnecting... 5/5 (additionalDetails: stream disconnected before completion: ... (os error 10061))
  2. Then it switches to an open-ended offline phase and keeps sending Reconnecting... waiting for network (additionalDetails: Connection failed: error sending request), still willRetry: true, about every 73 s, for as long as the network is down. It never sends a final willRetry: false.

CodexAdapterV2.ts (handleServerNotification("error", …)) builds the retry state like this:

ts
1const progress = parseCodexRetryProgress(payload.error.message);
2const retry = {
3 attempt: progress?.attempt ?? (previous?.retry.attempt ?? 0) + 1,
4 maxAttempts: progress?.maxAttempts ?? previous?.retry.maxAttempts ?? null,
5 retryDelayMs: null,
6};

waiting for network has no N/M, so progress is null: attempt increments and maxAttempts keeps the 5 from the earlier 5/5 message. providerErrorPresentation in apps/web/src/session-logic.ts then renders Retrying provider (6/5), (7/5), … (34/5).

Suggested fix: when a willRetry message carries no N/M (in particular Codex's waiting for network phase), don't inherit maxAttempts. Set it to null, so the label reads Retrying provider (34), or better, show a distinct "Waiting for network" label. Same code on main (8b44f42b14) today.

Steps to reproduce

  1. In ~/.codex/config.toml, point Codex at an endpoint that refuses connections, e.g.
    toml
    1model_provider = "dead"
    2[model_providers.dead]
    3name = "dead"
    4base_url = "http://127.0.0.1:9/v1"
    5wire_api = "responses"
    (Any unreachable endpoint will do: a stopped local proxy, network unplugged, etc.)
  2. Start a Codex thread in T3 Code and send a message.
  3. Watch the work log: Retrying provider (2/5) … (5/5), then (6/5), (7/5), … climbing about once a minute indefinitely.

Version

Server 0.1.7-nightly.20261104.4151 (commit 322f6544dfad), viewed from T3 Code Web 0.1.7 (app.t3.codes). Codex app-server 0.166.0. Code is unchanged on main (8b44f42b14) as of 2026-11-04.

Environment

Windows 11 x64, Node v24.22.1, local T3 server, web client (Chrome). Codex uses a custom model_provider (wire_api = "responses") via a local proxy on 127.0.0.1:8317.

Evidence

shell
1Provider event log, one turn over ~1h40m:
2
3
48 "Reconnecting... 2/5" … "5/5" details: stream disconnected before completion: ... actively refused it. (os error 10061)
586 "Reconnecting... waiting for network" details: Connection failed: error sending request
6willRetry: true on all 401 error notifications in the session; never false
7
8
9UI: "Working for 32m 53s / Retrying provider (34/5) / Connection failed: error sending request" (screenshot attached).

#28936: related Codex retry presentation problem (429 with Retry-After: label sticks at 1/5, never shows Limited). Different trigger, same providerRetries path. The fix may want to share how T3 presents Codex's open-ended retry phases.

Fix applied or workaround

Restarted the local proxy Codex's base_url points at; pending retries then succeeded and stuck turns resumed. This issue is only about the misleading counter.

Filed by

Claude Code (Claude Opus 5.5, claude-opus-5-5) via T3 Code triage.

Synced from GitHub

This is fixed by #29224, which is still open. It stops the Codex adapter from inheriting the earlier maxAttempts once retries switch to waiting for network, so the label reads Retrying provider (34) instead of (34/5). My duplicate, #30814, is closed in its favour.