Repository navigation
fix(runtime): retry the startup model probe once when the provider is unreachable - #2672
Conversation
… unreachable Codex reports a provider it cannot connect to as a Reconnecting network-wait notice and keeps waiting, so the startup probe ran to its timeout and held the notice at once as a fatal error event. Treat a network wait whose cause is a failed connection as transient, so it gets the existing single retry within the 61 s budget. Other Reconnecting notices the recovered-stream rule refuses stay held, and credential markers still veto. Finding 1618.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
… into the veto comment Review nits on finding 1618: a network wait with text after its cause stays held, the boundary shapes are labelled as such, and the transient comment names the network-wait exception in its first sentence.
freeqaz-openai
left a comment
There was a problem hiding this comment.
I reproduced the missing retry with the actual pinned codex-cli 0.163.0-alpha.2, then observed the corrected behavior through the generated entrypoint and its runtime-status endpoint.
| Same confirmed-refused loopback endpoint | Probe attempts | Final status; readiness |
|---|---|---|
Parent 7dcd2b67 |
1 | error-event after 30.2 s; never ready |
| Changed executable behavior | 2 | error-event-attempt2 after 61.2 s; never ready |
These are probe attempts, not a count of connections Codex may try inside one attempt. This was an existing runtime image carrying the pinned CLI, source-generated entrypoints, a synthetic credential, loopback-only networking and no external provider or Kubernetes deployment. The first generic offline control produced an ordinary timeout, which already retries; selecting an explicitly refused endpoint through the real configuration generator made the regression observable. The container exited and was removed.
At final c46fca08, the generated program differs from what I exercised by five comment lines only. All 127 final conformance tests passed; pairing the parent implementation with the new tests failed specifically on the unreachable-provider retry and held-cause assertions. Required CI and Image Model Probes succeeded on this exact head. This supports the bounded retry and diagnostic, not a claim that an arbitrary provider outage is a refused connection or that an unreachable model became available.
|
Codex review: needs maintainer review before merge. What this changesThe PR gives Codex’s exact failed-connection network-wait notice the existing single startup-probe retry. Example: The pinned Codex CLI probes a confirmed-refused loopback provider endpoint.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep open: this maintainer-authored PR repairs a verified gap in the existing startup retry policy, with no actionable defect found. Priority: P2 Before mergeNone. FindingsNone. Agent review detailsHow this fits togetherThe shared dedicated Codex runtime entrypoint receives admitted model configuration, runs the native authentication probe, and either starts the app server or exposes a held startup failure through runtime status. flowchart TD
A[Admitted Agent configuration] --> B[Dedicated runtime entrypoint]
B --> C[Native Codex model probe]
C --> D[Failure classification]
D --> E[One bounded retry]
E --> C
D --> F[Held failure status]
C --> G[Ready app server]
Technical reviewBest possible solution: Land the narrow classifier correction while preserving the existing retry budget and deterministic-failure exclusions. Do we have a high-confidence way to reproduce the issue? Current main visibly rejects the exact network-wait message before transient classification; the linked approval independently records the parent failure using the actual pinned CLI and generated entrypoint. Is this the best way to solve the issue? The change repairs the classification at its shared production owner, reuses the existing retry mechanism, and preserves the exclusions established by earlier fixes. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 0e997c497afa. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 16, 2026, 10:40 PM ET / October 17, 2026, 02:40 UTC. |
Problem
Finding 1618: with the model provider unreachable (connection refused), the dedicated Codex startup model check ran 30 s to its timeout and was held at once as
error-event, with no second attempt, although a failed connection is meant to keep its single retry.The pinned Codex build (
0.163.0-alpha.2) does not fail the turn on a failed connection. It printsand keeps waiting. A refused port, an unresolvable host and a failed TLS connection all print exactly this (checked by running the pinned binary against
http://127.0.0.1:1,http://no-such-host.invalidandhttps://127.0.0.1:9).codexTransientFailurevetoed everyReconnecting...notice, and the recovered-stream rule only accepts the boundedn/m ... stream disconnectedshape, so the first notice was held as fatal.Change
codexTransientFailurekeeps its veto on Reconnecting notices except one: a notice that is exactlyReconnecting... waiting for network (Connection failed: ...). That one is transient, so the probe takes the existing single retry inside the same 61 s budget (no new caps). Credential markers, rate limits, provider 4xx, certificate and NXDOMAIN rules still apply to it first.error-event-attempt2about a minute after the check starts.The retry-guard hunks of #2487 (the
providerTools === "none"error-event guard and the timeout retry) are untouched;git merge-treeagainst its head is clean.Verification
node --test tests/conformance/codex-native-startup.test.mjs: 127/127; 20/20 at 2 CPUs (taskset -c 0,1).error-event-attempt2when the second attempt sees the same; held at once: a network wait for a provider 503, a network wait that does not start the notice, a network wait with text after its cause, a network wait naming a credential (boundary shapes the pinned build does not print).Risks
Internal review: approve with nits (applied). With Credential Proxy Implementation #2487's
providerTools: "none"mode, an unreachable provider would still take this transient retry; nothing reached the provider, so that looks safe, but whoever lands Credential Proxy Implementation #2487 should know.Each attempt against an unreachable provider still waits out its 30 s limit, so such a deployment fails after about 61 s instead of 30 s.
A counted
Reconnecting... n/m (Connection failed: ...)shape is not printed by the pinned build and stays held; a Codex bump that changes the network-wait wording falls back to today's behavior (held at once).