openai / openai/codex

App-created heartbeat automation keeps firing 9 times after the usage limit is reached, draining the whole monthly Codex quota

Open
#45,070 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app automations bug rate-limits
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using?

Codex Desktop, cli_version 0.153.4

What subscription do you have?

Free (ChatGPT account, OAuth sign-in)

What platform is your computer?

macOS 27.0, arm64 (Apple Silicon)

What issue are you seeing?

An automation that the app created for itself (a heartbeat targeting an existing thread) kept firing on its schedule nine times after the account had already reached 100% of its monthly Codex quota. Each firing re-sent the entire conversation context of the target thread.

Net result: the whole 30-day monthly quota was consumed in a single day, and the account has no usable Codex allowance until the window resets on 2026-10-10.

Error on the final run:

You've hit your usage limit. Upgrade to Plus to continue using Codex
What steps can reproduce the bug?
  1. Work in a long-running thread and let it grow large. In my case the thread totalled 4,363,718 tokens (4,356,047 input, of which 4,165,888 cached; only 7,671 output).
  2. Ask the agent to "scan X periodically, and stop scanning once everything is confirmed complete". The agent then calls automation_update itself:
{
  "mode": "create",
  "kind": "heartbeat",
  "destination": "thread",
  "name": "OpenWorker status supervision",
  "rrule": "FREQ=MINUTELY;INTERVAL=10",
  "status": "ACTIVE"
}

It returns {"automationId":"openworker","mode":"create","status":"ACTIVE"} and targets the same existing thread.

  1. Let the account reach its usage limit. The automation does not stop — it continues firing on its interval. It is only stopped by manually deleting it.

Observed timeline (Europe/Rome, 2026-09-11). Session/thread id 01a08fa0-b8ee-7950-b0f1-6b6f4851e473, automation id openworker:

Time Event
12:14:39 automation created by the agent
12:16:38 monthly usage reaches 100%
12:25:08 firing #1 — quota already exhausted
12:35:39 firing #2
12:46:10 firing #3
12:56:40 firing #4
13:07:09 firing #5
13:17:40 firing #6
13:28:10 firing #7
13:38:40 firing #8
13:48:47 firing #9
13:48:49 run ends with the usage-limit error

Roughly 92 minutes of interval-based retries after the quota was already gone.

What is the expected behavior?
  • A scheduled automation should stop firing once the account has reached its usage limit. Retrying a heartbeat every 10 minutes against an exhausted quota has no possible benefit, and because every attempt re-transmits the full thread context it is the most expensive possible retry pattern.
  • The stop condition the user actually asked for ("stop scanning once everything is confirmed complete") should be honoured. Here it was not.
  • A heartbeat probably should not be attachable to a thread above some context-size threshold without an explicit warning, since each firing pays the full context cost.

Two concrete suggestions:

  1. Force a hard stop, or auto-pause the automation, on the first usage-limit error instead of waiting for the next interval.
  2. Warn, or require explicit confirmation, when creating a recurring automation whose target thread exceeds a configurable context-size threshold.
Additional information
  • The thread was archived automatically after the final failed run, so the automation had no useful target left while still firing.
  • Evidence for this report comes from the app's own records: the rollout event log (event_msg / token_count entries carry rate_limits.primary with used_percent, window_minutes: 43200, resets_at), and the automation row in the local app database.
  • The quota readings during the incident went 55% (10:41) → 85% (10:46) → 100% (12:16), i.e. the entire remaining monthly allowance was consumed inside one session on one thread.

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 with the automation_update entry point and the automation row in the local app database, then compare those records with rollout event log entries carrying rate_limits.primary. Trace what happens after the first usage-limit error and when the target thread is archived. Done means the automation stops or pauses at the limit and does not continue firing against an exhausted or unavailable target.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
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.