Allow custom model providers to disable automatic 401 auth recovery and replay
What variant of Codex are you using?
Codex CLI and Codex App (provider transport shared in codex-rs)
What feature would you like to see?
Summary
Custom model providers can set requires_openai_auth = true and can independently
configure normal request and stream retry budgets. There is currently no provider
setting that disables the separate recovery-and-replay path entered after an HTTP401 Unauthorized.
Please add an optional provider setting:
[model_providers.example]
name = "Example"
base_url = "https://example.invalid/v1"
wire_api = "responses"
requires_openai_auth = true
request_max_retries = 0
stream_max_retries = 0
auth_recovery_max_retries = 0
Expected behavior
- When
auth_recovery_max_retriesis absent, preserve the current behavior. - When it is
0, the first401must be returned through the existing provider
error mapping without refreshing/reloading authentication and without replaying
the logical provider request.
- When it is a positive integer
N, allow at mostN401-triggered recovery and
replay cycles for that logical provider invocation.
- Keep this budget independent from
request_max_retriesand
stream_max_retries.
- Apply the same rule to Responses HTTP and WebSocket connection paths.
Why this is needed
On both the released source corresponding to 0.146.0-alpha.3.1 and the checkedmain snapshot, a 401 enters handle_unauthorized(...) and a successful recovery
continues the surrounding loop, causing another provider request. Setting the
existing request and stream retry budgets to zero does not configure that separate
path.
Minimal acceptance tests
- Explicit zero + first HTTP request returns 401: one provider request, zero auth
recovery calls, no replay, original mapped 401 returned.
- Explicit zero + WebSocket connection returns 401: one connection attempt, zero
auth recovery calls, no reconnect caused by auth recovery.
- Positive budget of one: at most one recovery and one replay; a second 401 does
not cause a third provider request.
- Key absent: existing behavior remains unchanged.
- Invalid TOML values are rejected by the existing typed configuration/schema
path.
Scope
This request does not change endpoints, credential sources, token audiences,
fallback routing, the built-in OpenAI provider defaults, or telemetry schemas.
Verified source anchors
- Release:
rust-v0.146.0-alpha.3.1,
commit
ff75c5b939c477c49eb1bd5248da6dab71b109d1
- Checked
mainsnapshot:
61a44880a85d2fd0d8770908dea5733495e571c8
- Provider configuration:
codex-rs/model-provider-info/src/lib.rs
- 401 recovery and replay:
Additional information
A fuller local design proposal is attached for context. It is deliberately broader than this Issue; the requested implementation scope remains limited to the provider-scoped 401 recovery/replay budget described above.
Local proposal SHA-256: 3291ba284d98f8545f95b783e9636a57696f57fb9728fc063ecb2ebd1c01083e
OPENAI_CODEX_AUTH_RECOVERY_OTEL_UPSTREAM_PROPOSAL_CANDIDATE_V0.1.md
1 Comment
Agree that auth recovery is a distinct retry budget. It is also a replay boundary: a single logical provider invocation can fan out into multiple physical requests through transport retry, stream retry, and 401 recovery. The receipt should show one logical invocation ID, every physical attempt, the trigger for each replay, and the remaining budget.
auth_recovery_max_retries = 0then becomes auditable, not just configurable.If you add the setting, run the acceptance case through MartinLoop and send the receipt so we can verify there was exactly one provider attempt: https://github.com/Keesan12/martin-loop