app-server (chatgpt auth): turn idle timeout silently masks stale cf_clearance — only fixed by manual codex login

Open 💬 2 comments Opened May 11, 2026 by Dannyxiuzq
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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?

  1. Authenticate codex with auth_mode: "chatgpt".
  2. Drive codex app-server --listen stdio:// from a long-lived harness. Do not invoke interactive codex (so no automatic cookie refresh happens).
  3. Leave the system running for ~3–7 days.
  4. 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. Switching model or thinking does not help.
  5. Run codex login once. 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/updated notification, 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.json with id_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 of rawResponseItem/*, tool calls, model deltas, and turn/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/updated telemetry (explains why this notification looks like throttling when it isn't)
  • #22073, #21708, #12299 — concurrent reports of ChatGPT-mode quota anomalies (may share infrastructure)

View original on GitHub ↗

2 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #21346
  • #21899
  • #20673

Powered by Codex Action

Dannyxiuzq · 3 months ago

Reviewed the three bot-suggested duplicates. They share the broader "Cloudflare anti-bot challenge against chatgpt.com backend endpoints under auth_mode=chatgpt" root, but the failure surface here is distinct in four ways and the fixes proposed (or applied) in those issues do not address it.

| Issue | Failure surface | Workaround | Applies here? |
|---|---|---|---|
| #21346 | connectors/directory/list Cloudflare-challenged before MCP tool authorization | none proposed | No — main model completion path is fine in #21346; here it is the failing path. |
| #21899 | Discovery endpoints (connectors/directory/list, plugins/featured, tool_suggest) | codex features disable apps/plugins/tool_suggest | No — that issue explicitly reports MODEL_RESULT: OK; main completion keeps working after the workaround. Disabling discovery features does nothing about a stalled model turn. |
| #20673 | MCP server initialization (mcp-search handshake 403) | Clean reinstall + auth re-creation (issue closed) | No — that is functionally equivalent to codex login, which is the manual fix already noted here. The request here is for app-server to surface the stale-auth state, not for a user-side workaround. |

What is distinct about this issue:

  1. The failing path is the main model completion stream, not optional discovery / MCP endpoints. The other three explicitly report the model path as healthy.
  2. The harness mode is codex app-server --listen stdio:// driven over JSON-RPC, not interactive CLI / desktop / VS Code.
  3. There is no visible Cloudflare HTML / 403 / challenge token anywhere. The only client-side symptom is turn/completed never arriving, surfacing as codex app-server turn idle timed out waiting for completion.
  4. The recovery action is the same (codex login), but the requested fix is different: this issue asks app-server to emit a typed auth-required JSON-RPC event when the chatgpt session is no longer accepted by the backend, so harnesses can stop retrying / chasing model config and trigger re-auth instead of mis-attributing the stall to a slow model or rate limit.

Keeping this open as an app-server-mode sibling in the same family. Happy to add log captures or repro details if a triager needs them.