openai / openai/codex

Goal ignores an explicit human-hours pause and burns 1.26M tokens in 12 no-op turns

Open
#41,831 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server bug
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of Codex are you using?

Codex Desktop with connected codex-cli 0.150.1 runtime.

Model: gpt-5.6-sol, xhigh reasoning.

What platform are you using?

Nobara Linux 44, x86_64, kernel 7.2.0-202.nobara.fc44.x86_64.

When did this happen?

2026-08-31 in America/Sao_Paulo (UTC-03:00).

  • Session started: 08:29:14 local / 11:29:14 UTC
  • Goal created: 08:35:31 local / 11:35:31 UTC
  • Main work turn completed: 09:08:50 local / 12:08:50 UTC
  • Repeated continuation window: 09:08:50–09:10:33 local / 12:08:50–12:10:33 UTC
  • Goal status finally changed to paused: 09:10:28 local / 12:10:28 UTC
What happened?

I gave Codex a 737-line execution handoff for a private, multi-day implementation. The project context is intentionally anonymized, but the relevant handoff structure was:

  • eight ordered phases (0–7), with Phase 0 explicitly read-only;
  • research, correctness, compatibility, build, QA, worklog, and publication gates;
  • a resume capsule, evidence ledger, and worklog for cross-session state;
  • a maximum of 8 human-equivalent work hours per Monday–Friday day and 40 hours per week;
  • closeout counted inside the 8-hour cap, weekends with zero planned capacity, and unfinished work deferred to the next weekday;
  • an explicit requirement to stop working and pause when the human-equivalent capacity limit was reached;
  • remote publication prohibited until a late final-phase gate.

During the first work turn, I sent this additional instruction:

Set a Goal whose objective is completing this implementation, and always pause it when the human-time limit is exceeded.

Codex created an active Goal whose objective included completing all phases and gates while performing closeout and stopping at the 8-hour/40-hour human-equivalent limits.

When its worklog reached 8/8 human-equivalent hours for the day, Codex performed closeout and ended the main turn with a clear terminal response saying execution was paused until the next real weekday. The implementation was incomplete, so the Goal correctly was not marked complete. It also was not blocked.

However, the persisted Goal was still active. Only 79 ms after the main task_complete, the Goal continuation hook started a new turn and injected:

<codex_internal_context source="goal">
Continue working toward the active thread goal.
...
Tokens remaining: unbounded
...
Do not call update_goal unless the goal is complete or the strict blocked audit above is satisfied.
</codex_internal_context>

The assistant honored the handoff and responded that no work could occur because the 8/8-hour human-equivalent limit had been reached. As soon as each no-op turn completed, the hook immediately started another one. This repeated 12 times without user input or project work.

The loop stopped only after the persisted Goal status changed to paused. The rollout does not show an agent tool call that caused that status transition.

Sanitized event sequence
09:08:50.589 task_complete  # main work turn and daily closeout
09:08:50.668 task_started   # automatic continuation, +79 ms
09:08:51.263 internal goal continuation injected
09:09:01.955 assistant: goal remains active, execution paused until next weekday
09:09:02.071 task_complete
09:09:02.108 task_started   # automatic continuation again, +37 ms
...
09:10:26.791 task_started   # 12th automatic continuation
09:10:27.373 internal goal continuation injected
09:10:28.168 thread_goal_updated status=paused
09:10:33.395 task_complete

Total repeated-continuation duration: about 1 minute 43 seconds.

Token impact

These are recorded runtime counters, not a billing estimate:

Counter Before loop After loop Increase
total_token_usage.total_tokens 10,485,436 11,751,024 1,265,588
Input tokens 10,447,054 11,711,643 1,264,589
Cached input tokens 9,998,080 11,240,704 1,242,624
Output tokens 38,382 39,381 999
Goal tokensUsed 384,976 406,034 21,058

Each automatic no-op turn recorded roughly 98,772–112,114 total tokens because the same large context was reprocessed. Most were cached input, but the rollout's total token counter still increased by 1.26M and the Goal counter also increased.

Why the Goal contract could not honor the request

The agent-facing Goal lifecycle creates an active Goal, while the available update_goal operation only permits complete or blocked. It does not expose paused, waiting, or a wake time. The injected continuation context also explicitly forbids using blocked for an ordinary pause.

That leaves no valid agent action for this requested state:

Goal incomplete
+ daily human-equivalent capacity exhausted
+ preserve Goal for the next weekday
+ perform no more model turns until then

The assistant can say it is paused, but the scheduler still sees an active Goal and immediately requeues it.

Expected behavior
  • An explicit pause/stop condition inside the Goal objective must be able to persist a non-continuing state.
  • The agent should be able to set paused or waiting, ideally with an optional wakeAt timestamp.
  • The scheduler should re-check Goal state before enqueueing and before injecting a continuation.
  • Queued or in-flight continuation leases should be discarded after a pause.
  • Repeated semantically identical no-progress responses should trigger deduplication, backoff, and a low continuation/usage circuit breaker.
  • A time-based wait should not require misclassifying a healthy Goal as blocked.
  • The UI should expose that execution is paused while preserving the incomplete Goal.
Related issues
  • #34248 reports the same unbounded no-progress continuation class at much larger scale. This report adds a compact reproduction where the Goal objective itself contains an explicit human-hours stop gate.
  • #28144 requests durable wait/wake support without token usage, which would provide the missing lifecycle state here.

The full rollout contains private workspace details and is not suitable for public attachment. I can provide targeted sanitized event excerpts privately if needed.

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

Trace the Goal continuation hook, persisted Goal status, and update_goal lifecycle in codex-cli 0.150.1; begin by reproducing the 8/8-hour cap with the sanitized event sequence. Done means an incomplete Goal can remain paused without automatic continuation, with scheduler and UI behavior matching the expected pause semantics and regression coverage.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.