openai / openai/codex

Codex Desktop automatically marks Goal blocked after transient gpt-5.6-sol capacity errors without an update_goal call

Open
#41,808 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug connectivity session
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Codex App version

Codex Framework 151.0.7922.174; Codex runtime 0.151.0-alpha.7.1

Subscription

Pro

Platform

Darwin 25.5.0 arm64 arm

Summary

A long-running Codex Desktop Goal was automatically changed to blocked after transient model-capacity errors:

Selected model is at capacity. Please try a different model.

The user did not pause the Goal, and the agent did not call update_goal(status="blocked").

Observed state transition

A redacted local timeline from 2026-08-31:

2026-08-31 07:50:55Z | WebSocket disconnect | retrying sampling request (1/5 in 200ms)
2026-08-31 07:51:40Z | gpt-5.6-sol | medium | Selected model is at capacity
2026-08-31 07:51:40Z | Goal database status changed to blocked
2026-08-31 07:51:50Z | gpt-5.6-sol | medium | Selected model is at capacity
2026-08-31 07:53:14Z | gpt-5.6-sol | medium | Selected model is at capacity

A strict search found zero actual tool_name="update_goal" calls in the relevant window. The only loose text match came from tool/context documentation, not a tool invocation.

The task had already completed tools and made progress. Later continuation turns still executed after the persisted Goal status became blocked, leaving the scheduler, persisted Goal state, and UI inconsistent.

The same logs report:

  • full_context_window_limit_reached=false
  • token_limit_reached=false

This was therefore not a context-window or Goal token-budget stop.

Reproduction

  1. Start a long-running Goal in Codex Desktop.
  2. Use gpt-5.6-sol with medium reasoning.
  3. Let the Goal continue across multiple turns and execute tools.
  4. Encounter repeated transient Selected model is at capacity responses.
  5. Observe that ordinary WebSocket disconnects use the existing bounded retry path, while capacity errors terminate the turn without that retry path.
  6. After repeated capacity errors, inspect or resume the Goal.
  7. Observe that the Goal is persisted or displayed as blocked even though:
    • the user did not pause it,
    • the agent did not call update_goal(blocked),
    • later continuation turns can still execute.

The capacity response is backend-dependent and cannot be triggered deterministically.

Expected behavior

A transient model-capacity error should be classified as retryable and should not automatically convert an active Goal to blocked.

  • Retry with bounded exponential backoff.
  • Preserve completed tool results and accepted input.
  • If the retry budget is exhausted, enter a retained-state waiting or paused state with explicit retry controls.
  • Transition back to active when continuation resumes.
  • Reserve blocked for a genuine task impasse or an explicit supported state transition.

Related issues

  • #22390 — transient capacity errors should retry and retain task state
  • #36249 — Goal can enter a one-way blocked state after recoverable failure
  • #29370 — blocked Goal may remain blocked while resumed work runs
  • #35911 — gpt-5.6-sol + medium capacity error during compaction

This report adds a current Codex Desktop observation where the Goal database timestamp matches the capacity failure and no actual update_goal(blocked) call occurred.

Raw logs are intentionally not attached because they contain task content, thread IDs, local paths, tool arguments, and routing or authentication metadata. The timeline above is the redacted minimal evidence.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the Goal state transition and persistence path around repeated model-capacity errors, then compare it with the existing bounded WebSocket retry path. Verify behavior using the reproduction steps and related issues #22390, #36249, #29370, and #35911; done means capacity failures do not set an active Goal to blocked, retain progress, and provide a resumable waiting state after retries are exhausted.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.