Client or integration
Codex App
Area
Authentication and account pool
Summary
Pre-connection DNS and local network failures are currently recorded as failures of the selected Codex account. Regular Responses and native compact map every thrown non-timeout transport error to connect_error; after upstreamFailoverThreshold failures, OpenCodex soft-avoids that account, clears thread affinity, and changes the effective account.
This is incorrect for source-proven reachability failures such as ENOTFOUND, EAI_AGAIN, ENETUNREACH, ENETDOWN, EHOSTUNREACH, ECONNREFUSED, and equivalent bounded Bun error codes. Credential replacement cannot repair a machine-wide DNS or network outage, and concurrent agents can cross the default threshold almost immediately.
Expected behavior:
- Return the existing client-visible
502, but classify proven pre-connection DNS/network reachability failures as account-neutral.
- Do not increment account failure streak, set soft-avoid/cooldown, clear affinity, or change runtime/persisted active account.
- Release any owned quota-probe lease without treating the failure as account evidence.
- Inspect stable codes through a bounded cause chain; do not trust an unanchored message substring.
- Preserve current handling for
ECONNRESET, EPIPE, established-socket closure, TimeoutError, HTTP 5xx, actual 429/402, 401/403, and client cancellation.
Relevant source:
src/server/responses/core.ts: native passthrough transport failure recording.
src/server/responses/compact.ts: compact transport failure recording.
src/codex/routing.ts: transient streak, soft-avoid, affinity clear, and active failover.
src/lib/upstream-retry.ts: existing narrow transport classification.
src/codex/auth-context.ts: probe-lease release.
Required tests: table-driven bounded cause-chain classification; negative message-only cases; routing state unchanged after three neutral failures; regular and compact end-to-end ENOTFOUND cases; concurrent neutral failures; and proof that an owned probe lease is released. Existing reset/socket/timeout/HTTP failover regressions must remain.
Related: #186/#194 (established-connection and transient recovery, which this must not undo), #714 (retry/amplification rather than account-state mutation), and #504/#506 (thresholded account failover).
Reproduction
- Configure at least two Codex pool accounts and bind a thread to account A.
- Keep the default
upstreamFailoverThreshold: 3.
- Make the provider hostname unresolvable, or inject a pre-response error with stable code
ENOTFOUND.
- Send three concurrent or sequential requests.
- Restore network reachability and inspect the next routing decision.
Current: A is soft-avoided, affinity can be cleared, and another account can become effective.
Expected: requests may return 502 during the outage, but A's health, affinity, and active-account state remain unchanged.
Version
2.10.0; the relevant transport branches remained on dev at 075c2f34c060d068ed56985e76924a9f23aca39d when checked on 2026-08-03.
Operating system
Windows 11 Pro 10.0.26200; equivalent Node/Bun shapes should be covered on every supported platform.
Provider and model
OpenAI (Codex login / forward account pool); native Codex models.
Logs or error output
Provider unreachable: getaddrinfo ENOTFOUND <provider-host>
Screenshots and supporting files
None. Hostnames, account identifiers, and request identifiers are removed.
Redacted configuration
{
"providers": {
"openai": {
"adapter": "openai-responses",
"authMode": "forward",
"codexAccountMode": "pool"
}
},
"accountPoolStrategy": "fill-first",
"upstreamFailoverThreshold": 3,
"activeCodexAccountId": "__main__"
}
Checks
Client or integration
Codex App
Area
Authentication and account pool
Summary
Pre-connection DNS and local network failures are currently recorded as failures of the selected Codex account. Regular Responses and native compact map every thrown non-timeout transport error to
connect_error; afterupstreamFailoverThresholdfailures, OpenCodex soft-avoids that account, clears thread affinity, and changes the effective account.This is incorrect for source-proven reachability failures such as
ENOTFOUND,EAI_AGAIN,ENETUNREACH,ENETDOWN,EHOSTUNREACH,ECONNREFUSED, and equivalent bounded Bun error codes. Credential replacement cannot repair a machine-wide DNS or network outage, and concurrent agents can cross the default threshold almost immediately.Expected behavior:
502, but classify proven pre-connection DNS/network reachability failures as account-neutral.ECONNRESET,EPIPE, established-socket closure,TimeoutError, HTTP 5xx, actual429/402,401/403, and client cancellation.Relevant source:
src/server/responses/core.ts: native passthrough transport failure recording.src/server/responses/compact.ts: compact transport failure recording.src/codex/routing.ts: transient streak, soft-avoid, affinity clear, and active failover.src/lib/upstream-retry.ts: existing narrow transport classification.src/codex/auth-context.ts: probe-lease release.Required tests: table-driven bounded cause-chain classification; negative message-only cases; routing state unchanged after three neutral failures; regular and compact end-to-end
ENOTFOUNDcases; concurrent neutral failures; and proof that an owned probe lease is released. Existing reset/socket/timeout/HTTP failover regressions must remain.Related: #186/#194 (established-connection and transient recovery, which this must not undo), #714 (retry/amplification rather than account-state mutation), and #504/#506 (thresholded account failover).
Reproduction
upstreamFailoverThreshold: 3.ENOTFOUND.Current: A is soft-avoided, affinity can be cleared, and another account can become effective.
Expected: requests may return
502during the outage, but A's health, affinity, and active-account state remain unchanged.Version
2.10.0; the relevant transport branches remained ondevat075c2f34c060d068ed56985e76924a9f23aca39dwhen checked on 2026-08-03.Operating system
Windows 11 Pro 10.0.26200; equivalent Node/Bun shapes should be covered on every supported platform.
Provider and model
OpenAI (Codex login / forward account pool); native Codex models.
Logs or error output
Screenshots and supporting files
None. Hostnames, account identifiers, and request identifiers are removed.
Redacted configuration
{ "providers": { "openai": { "adapter": "openai-responses", "authMode": "forward", "codexAccountMode": "pool" } }, "accountPoolStrategy": "fill-first", "upstreamFailoverThreshold": 3, "activeCodexAccountId": "__main__" }Checks