#2883·manifest

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 with keyLabel, all connected 2026-09-09
  • Routing via header_tiers with override_route + fallback_routes that 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.0

Problems

  1. 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/*.
  2. 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.
  3. Fallback logs are ambiguous. ProxyFallbackService logs don't include keyLabel, so a fallback to the same model on a different account reads as trying model=X (primary=X), identical to a blind retry.
  4. Fallback failure reason isn't logged. When a fallback attempt fails (e.g. Fallback 0Fallback 1 in 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.
  5. 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 keyLabel unhealthy (cooldown or needs re-auth) and skip it in routing until it's fixed.
  • Include keyLabel, the failure status and a short upstream error in ProxyFallbackService logs 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. on kiro/claude-opus-5 (7×)
Image