Summary
Native Codex/app-server turns can be marked as failed after about 60 seconds even when the turn has already made meaningful progress or delivered user-visible updates via tools. The user-facing symptom is a generic channel error such as:
Something went wrong while processing your request. Please try again, or use /new to start a fresh session.
This has shown up in long-running Telegram sessions and background agents using Codex GPT-5.5. It is especially confusing when the agent has already sent useful updates, because OpenClaw later reports the whole request as failed.
Observed behavior
Recent logs showed the app-server wrapper aborting accepted Codex turns while waiting for turn/completed:
codex app-server turn idle timed out waiting for completion
LLM request timed out.
codex app-server attempt timed out
lastActivityReason values included notification:item/agentMessage/delta, notification:item/completed, notification:hook/completed, and notification:account/rateLimits/updated.
The important failure mode is that the per-request timeout can behave like a hard wall-clock timeout for a turn that has already started. Separately, account/rate-limit notifications can look like progress even though they do not prove the model is still advancing the current turn.
Expected behavior
OpenClaw should distinguish these cases:
- An accepted app-server turn should not be killed merely because the original request timeout elapsed.
- Meaningful turn progress should refresh the idle window, including turn/item/raw-response/tool/user-input/hook activity scoped to the current thread/turn.
- Account/rate-limit updates alone should not keep a stuck turn alive.
- A separate hard maximum should still cap genuinely wedged turns.
- If a messaging tool already delivered a visible channel update, OpenClaw should not emit a second generic timeout payload that makes a successful visible update look like a failed user request.
Suggested fix
I have a patch ready that:
- separates app-server request timeout from the hard turn timeout after
turn/start succeeds,
- raises the post-progress completion idle wait from 60s to 5m,
- keeps the terminal hard cap at 30m,
- refreshes the idle clock only for meaningful current-turn notifications/requests,
- excludes low-signal
account/* notifications from progress accounting,
- avoids a duplicate generic timeout response when
didSendViaMessagingTool is already true,
- adds regression tests for the accepted-turn timeout, progress refresh, account-only non-refresh, and message-tool timeout suppression.
Validation from the patch
Targeted checks pass locally:
pnpm exec vitest run extensions/codex/src/app-server/run-attempt.test.ts → 60 passed
pnpm exec vitest run src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts → 42 passed
pnpm tsgo:prod → passed
pnpm tsgo:test → passed
pnpm build → passed
Notes
The goal is not to let stuck turns run forever. The intended policy is progress-aware extension with a hard cap: let real work continue, but do not let low-signal heartbeats or account updates mask a wedged app-server turn.
Summary
Native Codex/app-server turns can be marked as failed after about 60 seconds even when the turn has already made meaningful progress or delivered user-visible updates via tools. The user-facing symptom is a generic channel error such as:
This has shown up in long-running Telegram sessions and background agents using Codex GPT-5.5. It is especially confusing when the agent has already sent useful updates, because OpenClaw later reports the whole request as failed.
Observed behavior
Recent logs showed the app-server wrapper aborting accepted Codex turns while waiting for
turn/completed:codex app-server turn idle timed out waiting for completionLLM request timed out.codex app-server attempt timed outlastActivityReasonvalues includednotification:item/agentMessage/delta,notification:item/completed,notification:hook/completed, andnotification:account/rateLimits/updated.The important failure mode is that the per-request timeout can behave like a hard wall-clock timeout for a turn that has already started. Separately, account/rate-limit notifications can look like progress even though they do not prove the model is still advancing the current turn.
Expected behavior
OpenClaw should distinguish these cases:
Suggested fix
I have a patch ready that:
turn/startsucceeds,account/*notifications from progress accounting,didSendViaMessagingToolis already true,Validation from the patch
Targeted checks pass locally:
pnpm exec vitest run extensions/codex/src/app-server/run-attempt.test.ts→ 60 passedpnpm exec vitest run src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts→ 42 passedpnpm tsgo:prod→ passedpnpm tsgo:test→ passedpnpm build→ passedNotes
The goal is not to let stuck turns run forever. The intended policy is progress-aware extension with a hard cap: let real work continue, but do not let low-signal heartbeats or account updates mask a wedged app-server turn.