Codex App main process hangs at 100% CPU: automation rrule iteration never terminates when INTERVAL is misaligned with BYMINUTE
What version of the Codex App are you using (From “About Codex” dialog)?
26.623.141536 (4753)
What subscription do you have?
ChatGPT Pro Lite
What platform is your computer?
Darwin 25.5.0 arm64 arm (macOS 26.5.2, Apple Silicon M4)
What issue are you seeing?
The Codex App main (browser) process gets pegged at 100% of one core and the whole app becomes unresponsive. On my machine a single automation-create request has been stuck for 16+ minutes of continuous 100% CPU (process cumulative CPU time 13:52 over 18:26 elapsed and still climbing at the time of writing).
I profiled the main process (sent SIGUSR1 to enable the V8 inspector on port 9229, then captured a CPU profile via the DevTools protocol). A 5-second profile (7914 samples) shows 99.6% self time in a single leaf, and the hot path has real symbol names:
(root)
handleMessage app.asar/.vite/build/main-8XtuV7fZ.js:855
handleRequest app.asar/.vite/build/main-8XtuV7fZ.js:373
handleVsCodeFetchRequest app.asar/.vite/build/main-8XtuV7fZ.js:373
automation-create app.asar/.vite/build/main-8XtuV7fZ.js:373 <- IPC handler
e.after app.asar/.vite/build/src-CoIhwwHr.js:395 <- RRule.after()
t._iter app.asar/.vite/build/src-CoIhwwHr.js:396
t.add app.asar/.vite/build/src-CoIhwwHr.js:393 <- 99.6% self time
e.after / t._iter / t.add is the bundled rrule library iterating occurrences. macOS sample confirms the main thread never returns to the event loop (all 3696 samples inside __CFRunLoopDoSource0 -> JS execution), so every IPC/UI interaction with the main process is blocked.
Root cause: the RRULE the automations feature generates can make rrule's occurrence iteration effectively non-terminating.
The automation being created had:
RRULE:FREQ=MINUTELY;INTERVAL=10;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9,10,11,12,13,14,15,16,17,18,19;BYMINUTE=0,10,20,30,40,50
with DTSTART = creation time, which was 16:27:55 local (minute :27). rrule iterates candidates starting from DTSTART and steps INTERVAL minutes each time, so the candidate minutes are 27, 37, 47, 57, 7, 17 (mod 60) — the BYMINUTE=0,10,20,30,40,50 filter never matches, and the iterator scans forward toward MAXYEAR (9999), i.e. hundreds of millions of synchronous iterations on the main thread.
Any rule of the form FREQ=MINUTELY;INTERVAL=N + a BYMINUTE list whose values are not congruent to DTSTART's minute modulo N triggers this. Whether it hits depends purely on the wall-clock minute at which the automation happens to be created/updated — which explains why the app "randomly" spins at 100% CPU on some days and not others. I have another persisted automation on disk (currently paused) with FREQ=MINUTELY;INTERVAL=30;BYMINUTE=5,35 and a created-at minute of :15 — same misalignment, so re-evaluating it would hang the app again.
App log timeline (~/Library/Logs/com.openai.codex/2026/07/08/codex-desktop-*-86148-t0-*.log): normal activity until an automation update/delete/re-create sequence at 08:27:39–08:27:55Z (turn/start, then "Deleted automation in the app" with "rrule":"RRULE:FREQ=MINUTELY;INTERVAL=10;..."), after which the log goes silent and the process spins — the re-create request never completes and the automation directory is never written.
What steps can reproduce the bug?
In the app: create (or have a conversation turn create) an automation "every 10 minutes, weekdays 9:00–19:59" at any wall-clock minute not divisible by 10. The generated rule is FREQ=MINUTELY;INTERVAL=10;BYMINUTE=0,10,20,30,40,50 with DTSTART = now, and the main process pegs at 100% CPU indefinitely. Affected conversation id: 019f4095-7299-7aa3-8a69-3b7b20edb68d.
Standalone repro with rrule 2.8.1 (same library, same rule, only DTSTART differs):
const { RRule } = require('rrule');
const mode = process.argv[2]; // "aligned" | "misaligned"
const dtstart = mode === 'aligned'
? new Date(Date.UTC(2026, 6, 8, 8, 20, 0)) // minute :20 (multiple of 10)
: new Date(Date.UTC(2026, 6, 8, 8, 27, 55)); // minute :27 (misaligned)
const rule = new RRule({
freq: RRule.MINUTELY,
interval: 10,
byweekday: [RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR],
byhour: [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
byminute: [0, 10, 20, 30, 40, 50],
dtstart,
});
const t0 = Date.now();
const next = rule.after(dtstart, false);
console.log(`rule.after() returned ${next && next.toISOString()} in ${Date.now() - t0} ms`);
Observed:
$ node repro.js aligned
rule.after() returned 2026-07-08T09:00:00.000Z in 1 ms
$ perl -e 'alarm shift; exec @ARGV' 30 node repro.js misaligned
(killed by SIGALRM after 30 s -- never returns)
What is the expected behavior?
- Creating/updating an automation returns promptly regardless of the wall-clock time it happens at.
- Schedule computation should not be able to block the Electron main process: normalize/validate generated RRULEs (e.g. drop
INTERVALwhen an explicitBYMINUTElist is given, or snap DTSTART to the BYMINUTE grid), and/or run occurrence computation off the main thread with an iteration cap/timeout.
Additional information
- This looks like a plausible root cause for at least some reports of "app idles at high CPU": #29374, #20735, #31531. The trigger is data-dependent (automation creation minute), which matches the intermittent nature of those reports.
- Happy to provide the full
.cpuprofile,sampleoutput, or logs if useful.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗