OpenAI subscription provider: 401 from Codex backend is never refreshed or marked unhealthy, so every request retries the dead credential before falling back (and fallback logs omit keyLabel/status)
Author: elvysmarcosCreated Sep 13, 2026Updated Sep 16, 2026
Summary
Environment
- Image:
manifestdotbuild/manifest:latest, self-hosted Docker, Postgres backend - Provider:
openai,auth_type=subscription(ChatGPT/Codex OAuth), 3 credentials withkeyLabel, all connected 2026-09-09 - Routing via
header_tierswithoverride_route+fallback_routesthat fan out across keyLabels, then copilot → opencode-go → kiro
What happens
Starting at 14:07, about 57% of requests routed to OpenAI subscription (211 of 367) fail on the primary attempt with 401:
DEBUG [ProviderClient] Forwarding to openai-subscription: https://chatgpt.com/backend-api/codex/responses
LOG [AutofixService] maybeHeal: failed forward status=401 ...
LOG [AutofixService] skip status=401: not in repairable set [400,404,422]
LOG [ProxyFallbackService] Fallback 0: trying model=gpt-5.6-terra provider=openai auth_type=subscription (primary=gpt-5.6-terra)
LOG [ProxyFallbackService] Fallback 1: trying model=copilot/gpt-5.6-terra provider=copilot auth_type=subscription (primary=gpt-5.6-terra)Model discovery for the same provider was already failing earlier (07:43):
WARN [ProviderModelFetcherService] Provider openai returned 401 from https://chatgpt.com/backend-api/codex/models?client_version=0.128.0Problems
- No OAuth refresh on 401. Nothing in the logs shows a token refresh attempt for the subscription credential after a 401 from
chatgpt.com/backend-api/codex/*. - No circuit breaking. A 401 is an auth failure, not a transient one, but the credential isn't marked unhealthy or cooled down. Every new request hits the failing key first, which adds latency and burns an upstream call before the fallback runs.
- Fallback logs are ambiguous.
ProxyFallbackServicelogs don't includekeyLabel, so a fallback to the same model on a different account reads astrying model=X (primary=X), identical to a blind retry. - Fallback failure reason isn't logged. When a fallback attempt fails (e.g.
Fallback 0→Fallback 1in the same second), neither the status code nor the upstream error body is logged, so you can't tell whether the second OpenAI account also got 401, 429 or something else. - No visible provider health. The failing credential still shows as
is_active=true, and nothing surfaces it in the UI or API.
Expected
- On 401 from an OpenAI subscription credential: try one token refresh; if that fails, mark that
keyLabelunhealthy (cooldown or needs re-auth) and skip it in routing until it's fixed. - Include
keyLabel, the failure status and a short upstream error inProxyFallbackServicelogs for every attempt. - Surface "credential needs re-authentication" in the provider list or dashboard.
Side notes seen in the same logs (possibly separate issues)
WARN [ProxyController] Failed to finish Provider Attempt recording: Error: ENOENT: no such file or directory, mkdir '/data/request-recordings/request-recordings'(131×, path segment duplicated)ERROR [ProxyController] Proxy error: Upstream provider stream was interrupted.onkiro/claude-opus-5(7×)
Source: mnfst/manifest