Desktop automations ignore timezone for RRULE scheduling / next execution

Open 💬 21 comments Opened Jun 5, 2026 by 0011001011
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex Desktop automations appear to display a weekly RRULE as a local wall-clock time, but the computed next execution behaves as if BYHOUR is interpreted in UTC. Adding an explicit DTSTART;TZID=Europe/Paris did not appear to affect the computed next execution.

Environment

  • Product: Codex Desktop app
  • Platform: macOS arm64
  • macOS: 26.5 (25F71)
  • Local Codex version metadata: latest_version: 0.136.0, last_checked_at: 2026-06-03T11:16:22.580528Z
  • Local timezone: Europe/Paris
  • Date observed: 2026-06-05, when Europe/Paris is UTC+2
  • Automation kind: cron
  • Execution environment: local

Reproduction

  1. Create or update a cron automation with this schedule:

``text
FREQ=WEEKLY;BYDAY=FR;BYHOUR=16;BYMINUTE=0;BYSECOND=0
``

  1. Open the automation list/detail in Codex Desktop while local timezone is Europe/Paris.
  1. Observe that the list shows the schedule as Fridays at 16:00, but the detail panel computes the next execution as 18:00 local time.
  1. Try to make the timezone explicit:

``text
DTSTART;TZID=Europe/Paris:20260605T160000
RRULE:FREQ=WEEKLY;BYDAY=FR;BYHOUR=16;BYMINUTE=0;BYSECOND=0
``

  1. The update is accepted, but the next execution still appears to be computed as 18:00 local time.

Expected behavior

A weekly automation configured for BYHOUR=16 in the user's local timezone, or with explicit DTSTART;TZID=Europe/Paris, should run at 16:00 Europe/Paris wall time. It should continue to stay at 16:00 across DST changes.

Actual behavior

The UI text says the automation is scheduled for Fridays at 16:00, but the computed next execution is 18:00 Europe/Paris on 2026-06-05. Since Paris was UTC+2 that day, this looks like BYHOUR=16 is being interpreted as 16:00 UTC.

The only workaround found was to change the stored RRULE to:

FREQ=WEEKLY;BYDAY=FR;BYHOUR=14;BYMINUTE=0;BYSECOND=0

That makes the next execution align with 16:00 Europe/Paris during DST, but it is brittle and will need to be changed to 15:00 UTC after the winter-time transition.

Impact

Scheduled automations that users configure for local wall-clock times can run one or two hours late/early depending on timezone and DST, while the UI still suggests the intended local time. This is especially confusing for automations that post messages or perform time-sensitive work.

View original on GitHub ↗

21 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #26588

Powered by Codex Action

un-n-smith · 2 months ago

I can reproduce the same timezone issue on Codex Desktop in Asia/Shanghai (CST, UTC+08:00), using a heartbeat automation.

Environment

  • Product: Codex Desktop
  • Version: 26.602.30954, build 3575
  • App path: /Applications/Codex.app
  • OS: macOS
  • System timezone: Asia/Shanghai, CST +0800
  • Local time confirmed with: date '+%Y-%m-%d %H:%M:%S %Z %z'
  • Automation kind: heartbeat

Reproduction

Update a heartbeat automation with this RRULE, intending Monday 08:15 local time:

FREQ=WEEKLY;COUNT=1;BYDAY=MO;BYHOUR=8;BYMINUTE=15;BYSECOND=0

The intended target was:

2026-06-08 08:15:00 CST +0800

The correct Unix milliseconds for that local time are:

1780877700000

However, Codex computed the next run as:

2026-06-08 16:15:00 CST +0800

That is equivalent to interpreting BYHOUR=8 as 08:15 UTC, not 08:15 in the system local timezone. The incorrect Unix milliseconds observed were:

1780906500000

Impact

This shifts fixed wall-clock automations by +8 hours on Asia/Shanghai systems. For time-sensitive staged workflows, the automation wakes at the wrong phase of the day even though the RRULE intent is a local wall-clock time.

Workaround

I had to manually verify and correct SQLite automations.next_run_at to the intended local-time Unix milliseconds, then verify by converting next_run_at / 1000 back to system local time.

Expected behavior: RRULE fixed-time schedules should respect the user's system local timezone, or Codex should expose an explicit timezone/TZID setting and make the UI and underlying next_run_at consistent.

hrygo · 2 months ago

Source code analysis confirms the dual-path timezone issue

I did a deep dive into the bundled Electron source (src-VjjkG3q_.js in Codex Desktop) and found the root cause. The scheduler has two code paths for computing the next run time:

Path 1: Optimized LOCAL path (for WEEKLY/DAILY)

The rc() function checks if a rule qualifies for an optimized path (no DTSTART, single clean rrule, interval===1, origOptions subset of {freq, interval, dtstart, tzid, byweekday, byminute, byhour}). For WEEKLY/DAILY, it uses JavaScript new Date(year, month, date, hour, minute) — which is LOCAL timezone.

// The wc() helper in the optimized path
function wc(now, time, weekdays) {
  let d = new Date(now);
  let day = d.getDay(); // LOCAL day
  // ...
  let s = new Date(d.getFullYear(), d.getMonth(), d.getDate() + n, time.hour, time.minute, 0, 0);
  // ^^^ LOCAL Date constructor -> BYHOUR is local time here
}

Path 2: Generic UTC path (for HOURLY and others)

Everything else falls through to rrule.js's .after() method, which operates in UTC. The BYHOUR values are then interpreted as UTC hours.

Why this matters

  • FREQ=WEEKLY;BYDAY=MO-FR;BYHOUR=0;BYMINUTE=0 -> Path 1 -> fires at local midnight (00:00 CST for me in UTC+8), not 00:00 UTC
  • FREQ=HOURLY;INTERVAL=1;BYDAY=MO-FR -> Path 2 -> fires in UTC hours
  • DTSTART;TZID=... is ignored because the Tc() check (origOptions.dtstart == null) routes rules with DTSTART to the generic rrule.js path, but even there TZID appears to be disregarded

Workaround

I adjusted all my BYHOUR values to be local time for WEEKLY rules (since they take Path 1). For hourly rules, I removed BYDAY entirely so the rule takes the interval path (ac() returns 3600000ms) and added a time guard in the prompt.

Environment

  • macOS arm64, timezone Asia/Shanghai (UTC+8)
  • Codex Desktop with local cron automations
  • Same behavior as the OP: UI shows one time, actual execution is offset by the timezone difference
chaochaoweb3 · 2 months ago

I have another reproduction from Codex Desktop on macOS in Asia/Shanghai (UTC+08:00), specifically with a daily heartbeat automation created from a natural-language local-time request.

Environment

  • Product: Codex Desktop on macOS
  • App release shown in logs: 26.602.71036
  • CLI version in session metadata: 0.137.0-alpha.4
  • Thread timezone in turn context: Asia/Shanghai
  • System local time confirmed as CST +0800
  • Automation kind: heartbeat

Reproduction / observed config

The user asked, in Chinese, for a message every day at 05:30 in the morning:

每天凌晨5点半给我发个消息,问现在几点了。

The saved heartbeat automation was:

kind = "heartbeat"
prompt = "现在几点了。"
status = "ACTIVE"
rrule = "FREQ=DAILY;BYHOUR=5;BYMINUTE=30;BYSECOND=0"

It was created at:

2026-06-09 11:23:08 CST +0800
2026-06-09T03:23:08Z

Expected behavior

Because the request and thread timezone are Asia/Shanghai, BYHOUR=5;BYMINUTE=30 should mean 05:30 Asia/Shanghai. Since the automation was created after 05:30 local time, the next run should have been:

2026-06-10 05:30:00 CST +0800
2026-06-09T21:30:00Z

Actual behavior

The heartbeat fired around:

2026-06-09T05:31:23Z
2026-06-09 13:31:23 CST +0800

That is consistent with interpreting BYHOUR=5 as 05:30 UTC, not 05:30 in the thread/system timezone.

A follow-up check around the expected local-time run window (2026-06-09T21:30Z, i.e. 2026-06-10 05:30 CST) found no automation-3 heartbeat/message records.

Additional failure in the same run

The run also failed to produce a user-visible heartbeat message. The app log contains:

[automations] Scheduled run failed automationId=automation-3 errorMessage="Heartbeat automation did not complete."

The corresponding session record has last_agent_message=null, so the run completed without a final heartbeat notification. The turn context for that scheduled run still showed collaboration_mode_kind="plan", which may be related to the heartbeat output not being emitted.

Current workaround

To make the automation fire at Beijing 05:30, I had to change the RRULE to UTC time manually:

rrule = "FREQ=DAILY;BYHOUR=21;BYMINUTE=30;BYSECOND=0"

This should result in 21:30 UTC == 05:30 Asia/Shanghai the next day, but it is confusing and fragile. The UI/config no longer matches the user's actual local-time intent.

Request

Please make heartbeat automations timezone-aware, or at least make timezone handling explicit in the UI/config. For natural-language scheduling requests, the expected default is the thread/system timezone (Asia/Shanghai here), not UTC. If heartbeat output fails (last_agent_message=null / Heartbeat automation did not complete), that failure should also be visible in the automation UI instead of silently looking like a missed reminder.

chaochaoweb3 · 2 months ago

I prepared a small public-repo branch related to this issue, but GitHub currently prevents me from opening a pull request because this repository appears to limit PR creation to collaborators.

Branch/commit:

Scope: this is not the full Desktop scheduler fix, because the Desktop automation scheduler implementation does not appear to be present in the public repository. The change adds test coverage that a deferred automation_update dynamic tool can expose a timezone field through tool_search output and follow-up routing.

Validated locally:

  • cargo fmt -p codex-core
  • cargo test -p codex-core tool_search --lib
  • cargo test -p codex-core --test all tool_search_returns_deferred_dynamic_tool_and_routes_follow_up_call

If maintainers can enable external PRs or point to the public source location for the Desktop scheduler, I can turn this into a proper PR.

princeAndRose · 2 months ago

Adding another repro from Asia/Shanghai with the current Codex Desktop build.

Environment

  • Subscription: Pro
  • Codex Desktop: 26.609.30741
  • Platform: macOS 15.6.1 (24G90), arm64
  • Local timezone: Asia/Shanghai (UTC+08:00)
  • Date observed: 2026-06-12
  • Automation kind: cron
  • Execution environment: local

What I observed

I have two active weekly cron automations. Their persisted automation.toml files contain the intended local wall-clock schedules:

# Team weekly automation
FREQ=WEEKLY;BYDAY=FR;BYHOUR=12;BYMINUTE=0;BYSECOND=0

# Personal weekly automation
FREQ=WEEKLY;BYDAY=FR;BYHOUR=18;BYMINUTE=30;BYSECOND=0

However, the scheduler state in $HOME/.codex/sqlite/codex-dev.db computed the next/last run timestamps as if BYHOUR were UTC:

team_next     local=2026-06-12 20:01:20 CST +0800  utc=2026-06-12 12:01:20 UTC
team_last     local=2026-06-05 20:01:52 CST +0800  utc=2026-06-05 12:01:52 UTC
personal_next local=2026-06-13 02:30:03 CST +0800  utc=2026-06-12 18:30:03 UTC
personal_last local=2026-06-06 02:31:54 CST +0800  utc=2026-06-05 18:31:54 UTC

So:

  • BYHOUR=12 is scheduled at about 20:00 local time in Asia/Shanghai.
  • BYHOUR=18;BYMINUTE=30 is scheduled at about 02:30 local time the next day.

The automation memory/run records also show runs at those shifted local times, including a team automation run around 2026-06-05 20:07 CST and a personal automation run around 2026-06-06 02:39 CST.

Additional note

In this local repro, there is also evidence of the same weekly automation running once near the intended local time and once near the UTC-interpreted local time. That looks similar to #26588, while the persisted next_run_at / last_run_at state matches this issue's UTC interpretation problem.

Expected behavior

A weekly cron automation configured through Codex Desktop for Friday 12:00 or Friday 18:30 should run at the user's local Asia/Shanghai wall-clock time, unless the UI/API clearly documents that BYHOUR is UTC.

The UI, automation.toml, and SQLite scheduler state should agree about whether RRULE wall-clock fields are local time or UTC.

Impact

For UTC+8 users, weekly automations can run eight hours late, including crossing into the next calendar day for evening schedules. This is disruptive for weekly reports, meeting-prep automations, reminders, and any time-sensitive automation.

zmievsa · 2 months ago

This issue happened to me as well. I'd love to fix it if codex team allows me to (i.e. PRs are invite-only).

Xiaofang-He · 1 month ago

I have the same problem as well, even I have asked the system to set up the timezone to be Asia/Shanghai time, it still add 8 hours automatically. Don't know how to fix this problem.

<img width="1128" height="776" alt="Image" src="https://github.com/user-attachments/assets/248efcc4-661d-489e-95ce-da50c36d3704" />

majur · 1 month ago

Adding another reproduction from Europe/Bratislava (CEST, UTC+02:00), observed today.

Environment

  • Product: Codex Desktop app
  • Platform: macOS
  • Local timezone: Europe/Bratislava / CEST (+0200)
  • Date observed: 2026-06-30
  • codex on PATH: codex-cli 0.130.0
  • Codex bundled with app: codex-cli 0.142.4
  • Automation kinds tested: cron and heartbeat
  • Execution environment for cron test: local

Local time verification

Shell time on the same host showed the expected local and UTC times:

date => 2026-06-30 20:09:05 CEST +0200
TZ=Europe/Bratislava date => 2026-06-30 20:09:05 CEST +0200
TZ=UTC date => 2026-06-30 18:09:05 UTC +0000

Reproduction

Created a one-shot cron automation intended to run at 20:04 Bratislava time:

DTSTART;TZID=Europe/Bratislava:20260630T200400
RRULE:FREQ=DAILY;COUNT=1

The saved automation was active, but no visible run/output appeared during active observation after 20:04 CEST. This looked consistent with a two-hour offset, as if the local wall-clock time was being treated as UTC.

Also tested a heartbeat automation in the same thread with a one-shot schedule. A schedule using DTSTART;TZID=Europe/Bratislava likewise did not wake at the expected local time. I then tried an explicit UTC DTSTART:20260630T181400Z for the equivalent local window; that also did not produce a visible heartbeat/run during the short observation window, so the most reliable signal here is the original timezone-aware schedule missing its expected CEST window.

Expected behavior

DTSTART;TZID=Europe/Bratislava:20260630T200400 should run at 20:04 Europe/Bratislava local wall-clock time and remain stable across DST changes.

Actual behavior

The automation did not trigger at the expected local-time window. The observed behavior matches the class of bugs described here where local timezone-aware automation schedules are effectively shifted by the UTC offset.

Impact

This affects mobile notification/reporting workflows. In my case I was setting up Codex automations to send HEY email notifications for reportable automation results. The email channel itself was verified independently via hey compose, but the scheduled Codex automation did not fire at the expected local time.

Contact

If maintainers need additional details from this repro, you can contact me at juraj@matase.sk.

neilpoulin · 1 month ago

I’m seeing the same issue in America/Denver.

Environment:

  • Product: Codex Desktop app
  • Platform: macOS
  • Local timezone: America/Denver
  • Date observed: 2026-07-01, MDT UTC-06
  • Automation kind: cron
  • Execution environment: local

Schedule:
DTSTART;TZID=America/Denver:20260701T090500
RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9,11,13,15;BYMINUTE=5;BYSECOND=0

Expected:
Runs at 9:05, 11:05, 13:05, 15:05 America/Denver.

Observed:
Runs appeared overnight/early morning, matching BYHOUR interpreted as UTC:
9,11,13,15 UTC => 3:05,5:05,7:05,9:05 MDT.

Workaround:
DTSTART:20260701T150500Z
RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=15,17,19,21;BYMINUTE=5;BYSECOND=0

That fixes the displayed next run during MDT, but will break at DST transition.

dj-thank · 1 month ago

I have a deterministic Windows / Asia-Tokyo reproduction that extends this bug to the YEARLY path and a calendar-year boundary.

Environment

  • Codex Desktop 26.707.3748.0
  • bundled CLI 0.144.0-alpha.4
  • Windows 10.0.26200 x64
  • system timezone Asia/Tokyo / Tokyo Standard Time

Reproduction

The automation was created at 2026-07-13 00:37:02 JST with:

FREQ=YEARLY;INTERVAL=1;BYHOUR=17;BYMINUTE=15;BYMONTH=7;BYMONTHDAY=12

The UI showed an annual schedule for July 12 at 17:15, but the card said Next run in 2 hours at approximately 2026-07-13 00:38 JST.

The stored value was:

next_run_at = 1783876500000
            = 2026-07-12 17:15 UTC
            = 2026-07-13 02:15 JST

That exactly explains the countdown: 00:38 JST to 02:15 JST is about 1 hour 37 minutes.

However, July 12 at 17:15 JST had already passed when the automation was created. The correct next occurrence is:

2027-07-12 17:15 JST
= 2027-07-12 08:15 UTC
= 1815380100000 epoch ms

So the YEARLY path both interprets BYHOUR=17 as UTC and selects the current-year UTC occurrence instead of advancing the already-expired local occurrence to 2027.

This matches the dual local/generic paths already analyzed in this thread and the +9-hour Asia/Tokyo behavior in #32304. It also reproduces on the exact Windows app build reported in #32236.

Suggested regression case:

now:    2026-07-12T15:38:52.378Z  (2026-07-13 00:38:52.378 JST)
tz:     Asia/Tokyo
rrule:  FREQ=YEARLY;INTERVAL=1;BYHOUR=17;BYMINUTE=15;BYMONTH=7;BYMONTHDAY=12
want:   2027-07-12T08:15:00.000Z
reject: 2026-07-12T17:15:00.000Z

The UI summary, stored next_run_at, and runner should all use the same normalized schedule and IANA timezone. A fixed UTC offset would not be sufficient for DST-observing zones.

niieani · 1 month ago

Confirming this still affects actual cron execution, not only the displayed next-run time, on a current Codex Desktop build.

Environment

  • Codex Desktop: 26.707.72221 (build 5307)
  • macOS: 26.5.2 (25F84), arm64
  • System timezone: America/Los_Angeles / PDT (UTC-07:00)
  • Automation kind: cron
  • Execution environment: local

Reproduction

I had a weekly automation intended to run Wednesday at 15:00 Los Angeles time. Its persisted recurrence included an explicit timezone:

DTSTART;TZID=America/Los_Angeles:20260715T150000
RRULE:FREQ=WEEKLY;BYDAY=WE

Expected first run:

2026-07-15 15:00 PDT
2026-07-15T22:00Z

Actual task-thread creation:

2026-07-15 08:01:45 PDT
2026-07-15T15:01:45Z

The seven-hour difference exactly matches treating the persisted 15:00 wall-clock value as UTC. The automation's task appeared in the local thread database at 08:01 PDT and began running then.

I separately verified that the host timezone was PDT (-0700). The automation file had not changed since July 9, so this was not caused by a schedule edit around execution time.

Impact

This caused a substantial weekly workflow to start seven hours early. Because the saved schedule correctly names America/Los_Angeles, the configuration and UI give no indication that actual execution will use UTC instead.

This reproduction confirms the bug persists in build 26.707.72221 and affects the runner itself.

altiratech · 1 month ago

I reproduced a closely related one-time heartbeat variant on macOS 26.5.2 in America/New_York on 2026-07-17.

At approximately 21:17 EDT, I created an ACTIVE heartbeat intended to run once at 23:42 EDT using:

RRULE:FREQ=DAILY;COUNT=1;BYHOUR=23;BYMINUTE=42

The Automations list displayed “Daily at 11:42 PM” but reported “Next run in 23 hours,” rather than roughly 2 hours 25 minutes. The scheduler had effectively selected tomorrow despite displaying the intended local wall-clock time.

I then attempted to anchor the same future occurrence explicitly:

DTSTART;TZID=America/New_York:20260717T234300
RRULE:FREQ=DAILY;COUNT=1

The automation update API rejected it with:

Automation schedule has no future runs. Choose a schedule with an occurrence after the current time.

The machine's verified local time was 2026-07-17 21:19 EDT, so that DTSTART was still more than two hours in the future.

The equivalent UTC instant was accepted:

DTSTART:20260718T034300Z
RRULE:FREQ=DAILY;COUNT=1

This appears to affect both next-run computation for a floating/local RRULE and validation of an explicit TZID DTSTART. Existing recurring automations on the same machine use local BYHOUR rules normally, so the UTC form was only a workaround for this one-time run.

terry-li-hm · 1 month ago

Adding a current Asia/Hong_Kong reproduction that narrows this to a dual-path inconsistency between automation_update first-run seeding and later RRULE evaluation.

Environment:

  • Codex Desktop 26.715.31925, build 5551
  • macOS 26.5.2 build 25F84, arm64
  • Timezone Asia/Hong_Kong, UTC+08:00
  • Automation kind cron, execution environment local

I used the app's automation_update handler to create a weekly automation with this UTC-coded workaround, intending Monday 09:30 HKT:

FREQ=WEEKLY;BYDAY=MO;BYHOUR=01;BYMINUTE=30;BYSECOND=00

The handler persisted the RRULE unchanged, but initialized next_run_at as approximately 2026-07-20 01:31 HKT, rather than 2026-07-20 09:30 HKT. In other words, the create or update path treated BYHOUR=01 as local time, while the runner behavior documented in this issue treats it as UTC.

This repeated across three independent updates:

SU 01:15 UTC-coded -> seeded about 01:16 HKT, expected 09:15 HKT
MO 01:00 UTC-coded -> seeded about 01:01 HKT, expected 09:00 HKT
WE 00:00 UTC-coded -> seeded about 00:01 HKT, expected 08:00 HKT

I corrected only automations.next_run_at to the intended HKT instants while leaving the UTC-coded RRULEs intact. The resulting pairs are now internally consistent, for example BYHOUR=01;BYMINUTE=30 with next_run_at=2026-07-20T01:30:00Z, displayed locally as 2026-07-20 09:30 HKT.

This appears to corroborate the dual-path source analysis already posted above: the mutation handler seeds the first occurrence using local wall time, while the scheduler later evaluates the same stored RRULE as UTC. That split also explains the reported risk of one run near the locally seeded time and another after UTC-based recomputation. A regression test should assert that create or update, displayed next run, persisted next_run_at, and actual execution all use the same timezone interpretation.

cjscld · 1 month ago

Adding a deterministic Asia/Seoul reproduction that narrows the dual-path timezone issue specifically to the presence of BYSETPOS.

Environment

  • Codex Desktop: 26.715.52143 (build 5591)
  • macOS: 27.0, arm64
  • System timezone: Asia/Seoul / KST (UTC+09:00)
  • Automation kind: cron
  • Execution environment: local
  • Observed: 2026-07-21 at approximately 07:52 KST

Controlled reproduction

I created three active cron automations seconds apart in the same local project, with the same prompt, model, and execution settings. The candidate occurrence set was intentionally kept identical.

A — baseline

RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9,10,13,14;BYMINUTE=20,30

UI result:

Next run in 2 hours

This is consistent with the next occurrence being 09:20 KST.

B — baseline plus BYSECOND=0

RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9,10,13,14;BYMINUTE=20,30;BYSECOND=0

UI result:

Next run in 2 hours

This also stays on the local-time path, so BYSECOND is not the trigger in this reproduction.

C — baseline plus a no-op BYSETPOS

RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9,10,13,14;BYMINUTE=20,30;BYSETPOS=1,2,3,4,5,6,7,8

UI result:

Next run in 11 hours

The eight candidate times are 09:20, 09:30, 10:20, 10:30, 13:20, 13:30, 14:20, and 14:30. Because BYSETPOS selects all eight positions, it is semantically a no-op and should not change the recurrence set.

However, the 11-hour countdown is consistent with 09:20 being interpreted as UTC and therefore becoming 18:20 KST. The exact nine-hour shift matches the local UTC offset.

Expected behavior

All three rules should calculate the same next occurrence, 09:20 KST. Adding a no-op BYSETPOS must not change the timezone used to evaluate BYHOUR.

Actual behavior

Adding BYSETPOS alone changes the next-run calculation from local time to UTC, even though it does not remove any occurrence. This appears to provide a minimal regression case for the optimized-local versus generic-UTC path described in the earlier source analysis.

This reproduction verifies the displayed next-run calculation. I did not wait for the automations to execute.

jkjoplin · 1 month ago

Adding a current reproduction and feedback reference for this issue.

  • Codex Desktop: 26.715.72359 (build 5718)
  • Bundled CLI: 0.145.0-alpha.30
  • Platform/timezone: macOS, America/Denver (MDT, UTC-06:00)
  • Intended schedule: weekdays, hourly from 08:00 through 18:00 local time
  • Observed July 22 runs: 02:15, 03:13, 04:16, 05:00, 06:15, and 07:01 MDT, consistent with the configured BYHOUR values being interpreted as UTC despite an explicit TZID=America/Denver.
  • The persisted automation still showed the timezone-aware recurrence. Updating the recurrence and pausing/reactivating the automation did not immediately prevent the UTC-shifted executions.

Feedback reference ID: 019f8548-80e8-7741-ab0b-b0af2ecf438e

marcodallagatta · 1 month ago

Confirmed on macOS in Europe/Berlin. While CEST is UTC+02:00, a task configured for 09:00 local was computed to run at 11:00 local. The Mac system clock reports CEST +0200. This makes the current offset workaround brittle across the DST change. Please apply the local IANA timezone to execution, not only display it.

Feedback ID 019f8e13-f800-71e1-b5e2-aecafa6833eb

louisaquino14 · 25 days ago

Additional Windows / UTC+08 reproduction from Codex Desktop automation creation on 2026-08-03.

Environment

  • Codex Desktop Windows package: OpenAI.Codex 26.727.6591.0 x64
  • Bundled/current CLI: codex-cli 0.144.0
  • OS timezone ID: Singapore Standard Time
  • Effective user timezone: Philippine Time / Asia/Manila, UTC+08:00
  • Automation kind: cron
  • Execution environment: local

Intended schedules

Two four-occurrence daily automations were requested for August 4–7, 2026:

  • 10:00 AM PHT (02:00 UTC)
  • 2:00 PM PHT (06:00 UTC)

Reproduction and observed behavior

  1. A timezone-anchored immediate create was attempted with a UTC DTSTART:

``text
DTSTART:20260804T020000Z
RRULE:FREQ=DAILY;COUNT=4
``

  1. automation_update rejected the immediate create with:

``text
Immediate automation creates cannot include DTSTART because it may change
local wall-clock times to UTC. Omit DTSTART, or retry with
mode=suggested_create when the user intentionally requested anchored or
timezone-specific RFC semantics.
``

  1. Retrying an immediate create without DTSTART, using the requested local wall-clock hours:

``text
RRULE:FREQ=DAILY;COUNT=4;BYHOUR=10;BYMINUTE=0
RRULE:FREQ=DAILY;COUNT=4;BYHOUR=14;BYMINUTE=0
``

returned only a generic success response. The UI/countdown treated the hour as UTC: the 10:00 rule resolved to 18:00 PHT, roughly four hours after creation, rather than 10:00 PHT the next day.

  1. Updating the persisted rules to the corresponding UTC hours:

``text
RRULE:FREQ=DAILY;COUNT=4;BYHOUR=2;BYMINUTE=0
RRULE:FREQ=DAILY;COUNT=4;BYHOUR=6;BYMINUTE=0
``

makes the computed instants correspond to 10:00 AM and 2:00 PM PHT. However, the rendered automation cards still show misleading wall-clock labels rather than the intended PHT schedule. In this reproduction the user saw labels including 7:30 AM (matching an unrelated existing automation) and 2:00 AM, instead of 10:00 AM and 2:00 PM PHT. This also suggests the card rendered by an automation view/create response may be stale or associated with the wrong automation ID.

Expected

  • Immediate automation creation should accept an explicit TZID or UTC DTSTART.
  • The create/update response should return the canonical recurrence, effective timezone, and computed nextRunAt.
  • List/detail/tool-rendered cards should all show the same user-local time and timezone.
  • Viewing an automation by ID should never render the label/schedule from another automation.

Impact

This is unsafe for time-sensitive unattended operations. The API reports success while neither the agent nor user can reliably confirm the actual next execution from the returned data, and the UI labels can disagree with the computed instant.

Related display-only report: #28693.

louisaquino14 · 25 days ago

Follow-up from the same Windows / Asia-Manila reproduction (Codex app 26.727.6591.0, CLI 0.144.0):

  • With DTSTART:20260804T020000Z + daily recurrence, the database next_run_at is 2026-08-04T02:00Z = 10:00 AM PHT, and the UI countdown is consistent with 10:00 AM PHT, but the Scheduled tasks subtitle renders Daily at 2:00 AM.
  • With DTSTART:20260804T060000Z, the database next run is 06:00Z = 2:00 PM PHT, while the subtitle renders Daily at 6:00 AM.
  • Switching to DTSTART;TZID=Asia/Manila:20260804T100000 makes both the timezone name and local time visible in the rule, but the scheduler stores 10:00Z = 6:00 PM PHT (TZID is ignored for execution).
  • An explicit numeric-offset form (20260804T100000+0800) is rejected by automation update.

So on this build there appears to be no representation that simultaneously gives a correct local subtitle and a correct execution instant. I reverted to explicit UTC to keep execution safe; the displayed subtitles remain wrong.

niieani · 13 days ago

There's a lot of comments here, but not many upvotes of the original issue. Please upvote the issue so that it becomes more visible for OpenAI so they prioritize a fix!

FiniusPortalis · 11 days ago

Adding an Asia/Tokyo reproduction on the current ChatGPT/Codex Desktop build, specifically for the RDATE-only path.

Environment

  • ChatGPT/Codex Desktop: 26.810.52044 (build 6662)
  • macOS: 26.6.1 (25G76), arm64
  • System and turn timezone: Asia/Tokyo
  • Automation kind: heartbeat
  • Observed: 2026-08-17

Actual execution

The first occurrence was stored as:

RDATE;TZID=Asia/Tokyo:20260817T074500

Expected:

2026-08-17 07:45 JST = 2026-08-16T22:45:00Z

Actual heartbeat:

current_time_iso=2026-08-17T07:45:06.011Z
= 2026-08-17 16:45:06 JST

This is an exact +9 hour shift.

Short deterministic probe

I created a one-time heartbeat with:

RDATE;TZID=Asia/Tokyo:20260817T174000

Immediately after creation, the scheduler persisted:

next_run_at=2026-08-17T17:40:00Z
= 2026-08-18 02:40 JST

It did not fire at the intended 17:40 JST and was deleted before the delayed execution.

Workaround

Using an explicit UTC instant:

RDATE:20260817T224500Z

produced the correct next run:

2026-08-18 07:45 JST

The system timezone was correctly configured as Asia/Tokyo. This suggests the RDATE-only path discards or ignores TZID and parses the date-time fields as UTC. The issue still reproduces in version 26.810.52044.