app-server (chatgpt auth): turn idle timeout silently masks stale cf_clearance — only fixed by manual codex login
What version of Codex CLI is running?
codex-cli 0.128.0 (driving the bundled codex app-server over stdio).
What subscription do you have?
ChatGPT pro plan (auth_mode: "chatgpt" in ~/.codex/auth.json; no OPENAI_API_KEY).
Which model were you using?
gpt-5.5 primary with gpt-5.4 configured as the model-fallback target. Both fail in the same way before re-auth.
What platform is your computer?
Darwin 25.2.0 arm64 arm .
What terminal emulator and version are you using (if applicable)?
N/A — no interactive terminal involved. codex app-server --listen stdio:// is spawned by a long-lived harness (OpenClaw gateway 2026.5.7-beta.1) running under launchd, driving turns over JSON-RPC.
What issue are you seeing?
Long-lived codex app-server sessions under auth_mode: "chatgpt" enter a state where every turn fails with codex app-server turn idle timed out waiting for completion after roughly 10–13 minutes. The model-fallback path (5.5 → 5.4) does not help; the fallback target also times out (model fallback decision: candidate_failed ... reason=timeout next=none).
A single codex login (refreshing ~/.codex/auth.json) immediately fixes it. The same harness, same cron job id, same prompt, and same model/thinking config that failed five attempts in a row succeeded on the first attempt after re-auth.
This looks like the app-server-mode manifestation of #17880 (cf_clearance / Cloudflare WAF cookie staleness in chatgpt auth mode). In app-server mode there is no surfaced auth error — only opaque idle timeouts that look identical to a slow model or rate limit, so harnesses cannot distinguish, cannot auto-recover, and waste real money on retries.
Concrete timeline today , same cron job :
| Time | Trigger | Model | Result | Tool calls before stall |
|---|---|---|---|---|
| 05:00 | scheduled | gpt-5.4 + xhigh | turn idle timeout | 2 |
| 17:36 | manual retry | gpt-5.4 + xhigh | turn idle timeout | 17 |
| 18:21 | manual retry | gpt-5.5 + high | runtime watchdog abort after 631s; lastProgress=codex_app_server:notification:account/rateLimits/updated, lastProgressAge=138s, but per #22054 that notification is benign per-turn telemetry — the snapshot did not carry rate_limit_reached_type | 0 |
| 19:15 | user runs codex login | — | auth.json mtime refreshed | — |
| 19:16 | manual retry, same config as 18:21 | gpt-5.5 → fallback gpt-5.4 | success in 13:50, trajectory session.ended.status = "success" | 25 |
auth.json had not been refreshed for ~4 days before the failure window. No interactive codex activity in that window; only the headless app-server.
What steps can reproduce the bug?
- Authenticate
codexwithauth_mode: "chatgpt". - Drive
codex app-server --listen stdio://from a long-lived harness. Do not invoke interactivecodex(so no automatic cookie refresh happens). - Leave the system running for ~3–7 days.
- Submit a heavy turn (long-running, many tool calls, large context). The turn times out with
codex app-server turn idle timed out waiting for completion. Subsequent attempts fail identically. Switchingmodelorthinkingdoes not help. - Run
codex loginonce. Retrigger the exact same prompt. It succeeds.
What is the expected behavior?
When the chatgpt-mode session cookie / cf_clearance is no longer accepted by the backend, codex app-server should surface a typed authentication-required error over JSON-RPC instead of silently dropping the turn/completed reply. Today this is indistinguishable from a slow model or a real rate limit, which:
- Confuses harnesses into retrying instead of prompting the user to re-auth.
- Confuses harnesses into chasing model/thinking config changes that cannot fix the underlying cookie staleness.
- Misleads diagnostics — the only "last progress" the harness sees is the
account/rateLimits/updatednotification, which (per #22054) is benign telemetry. It is easy to misread as throttling proof.
Better still: app-server could proactively detect a stale cf_clearance (e.g. response shape no longer JSON / arrives as Cloudflare HTML challenge) and either silently re-auth or emit a auth/required event for the harness to handle.
Additional information
- Auth file before fix:
~/.codex/auth.jsonwithid_token+ refresh token, last mtime > 90h before the failure window. - The harness logs every event it gets from app-server. On the failing turns the only post-prompt event before idle timeout is
account/rateLimits/updated(per turn), then nothing arrives until the watchdog fires. - On the recovered turn after
codex login, the harness sees a normal stream ofrawResponseItem/*, tool calls, model deltas, andturn/completed— same prompt, same model. - No relevant change on the user side between the failing and successful attempts other than running
codex login.
Related:
- #17880 — Recursive Context Poisoning (Cloudflare/WAF) triggering persistent History Loss and False Rate Limits (same suspected root, different surface)
- #22054 — Gate benign
account/rateLimits/updatedtelemetry (explains why this notification looks like throttling when it isn't) - #22073, #21708, #12299 — concurrent reports of ChatGPT-mode quota anomalies (may share infrastructure)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗