Codex App: explicit same-thread heartbeat creation falls back to a non-persistent “Proposed” card after DTSTART validation
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.825.3734.0
What subscription do you have?
ChatGPT Pro (20x)
What platform is your computer?
Microsoft Windows 11 Home Single Language 10.0.26200 (build 26200), x64
What issue are you seeing?
When a user explicitly asks Codex Desktop to create a one-off scheduled task attached to the current chat, the task may be converted into a non-persistent suggested_create proposal after DTSTART validation fails.
The suggested_create call returns a successful tool result (isError: false) and the application renders an automation card. However, the card is only marked Proposed: no automation is persisted, no automation ID is returned, and the scheduled-task clock indicator does not appear on the chat.
Because the tool invocation is reported as successful, the agent can incorrectly interpret the result as confirmation that the requested task was created. The user only discovers that nothing was scheduled when the clock icon does not appear or when they explicitly ask the agent to verify persistence.
This is not a delayed UI refresh or a target_thread_id problem. Retrying the same request using a direct create call without DTSTART immediately persists the automation, returns an automationId, and attaches the correct target_thread_id.
Observed user-visible sequence:
- The user explicitly asks Codex to create a scheduled task attached to the current chat.
- Codex calls
automation_updatewithmode: "create"and an RRULE containing a timezone-specificDTSTART. - The call fails validation and instructs the agent to omit
DTSTARTor usemode: "suggested_create". - The agent retries with
mode: "suggested_create". - The tool returns success and renders a
Proposedautomation card. - No automation is saved and the chat receives no scheduled-task clock indicator.
- A later direct
createcall withoutDTSTARTsaves the task successfully.
The dangerous part is the mismatch between the user's explicit create intent, the successful tool result, and the actual persistence state. The user can reasonably believe that a future task is scheduled when no task exists.
What steps can reproduce the bug?
The problem was reproduced in the Europe/Moscow timezone.
-
Open an existing Codex Desktop chat.
-
Ask Codex:
Schedule a deferred task attached to this chat for tomorrow at 2:00 AM.
-
Observe the initial
automation_updatecall. In the reproduced session it was equivalent to:{
"mode": "create",
"kind": "heartbeat",
"destination": "thread",
"name": "Reproduction",
"prompt": "",
"status": "ACTIVE",
"rrule": "DTSTART;TZID=Europe/Moscow:20260829T020000\nRRULE:FREQ=DAILY;COUNT=1"
} -
The call fails with:
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. -
Retry exactly as suggested by the error, changing only the mode:
{
"mode": "suggested_create",
"kind": "heartbeat",
"destination": "thread",
"name": "Reproduction",
"prompt": "",
"status": "ACTIVE",
"rrule": "DTSTART;TZID=Europe/Moscow:20260829T020000\nRRULE:FREQ=DAILY;COUNT=1"
} -
The tool returns a non-error result containing:
Rendered automation card in the app. -
UI displays a Proposed automation card, but:
- no automation ID is returned;
- no active automation is persisted;
- no scheduled-task clock appears on the current chat;
- reopening or checking the automations list confirms that the task does not exist.
-
Now create the same task directly, without DTSTART:
{
"mode": "create",
"kind": "heartbeat",
"destination": "thread",
"name": "Reproduction",
"prompt": "",
"status": "ACTIVE",
"rrule": "RRULE:FREQ=DAILY;COUNT=1;BYHOUR=2;BYMINUTE=0;BYSECOND=0"
} -
This call succeeds immediately, returns an automationId, persists the automation, and sets target_thread_id to the current chat.
The exact thread ID, automation ID, and task prompt have been redacted because they are not required to reproduce the control-flow bug.
What is the expected behavior?
An explicit request to create a scheduled task should result in one of the following unambiguous outcomes:
- The task is persisted and the tool returns an
automationId; or - The task is not persisted, and the tool explicitly reports that user action is still required.
For this particular request, Codex should preferably preserve the original create intent and retry mode: "create" with an equivalent RRULE that does not contain DTSTART.
A suggested_create result must not be indistinguishable from a completed create operation. If proposals are intentionally non-persistent, the structured result should include fields such as:
{
"persisted": false,
"requiresUserAction": true,
"action": "review_and_save"
}
Additional information
Additional information
Root-cause evidence
Inspection of the session trace and the locally installed Codex Desktop bundle indicates the following control flow:
createandsuggested_createare exposed as separate tool modes.- The
createvalidator rejects RRULEs containingDTSTART. - Its error text recommends
suggested_createfor anchored or timezone-specific schedules. suggested_createis normalized to an internal suggested-create operation.- The persistence handler saves only actual create/update/delete operations.
- The suggested-create path renders a proposal card and returns a successful tool result, but does not persist an automation.
- The rendered row is labelled
Proposed. - Clicking the proposed row opens a pre-filled editing form; it is not equivalent to saving the automation.
This means the scheduler itself is not failing. The failure is at the boundary between:
- validation and recovery guidance;
- explicit create intent and suggestion intent;
- tool-level success and persistence success;
- the agent's completion criteria and the UI's
Proposedstate.
Suggested fixes
Any combination of the following would prevent the failure:
-
When an explicit create request contains
DTSTART, make the preferred recovery path a directcreateretry with an equivalent DTSTART-free RRULE. -
Only use
suggested_createwhen the user explicitly asked to review a proposal before saving. -
Return an explicit structured state for proposals:
{
"persisted": false,
"requiresUserAction": true
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the automation_update create validator, the suggested_create normalization path, and the persistence handler described in the root-cause evidence. Reproduce the DTSTART failure and compare the create and suggested-create results. Done means explicit create requests either persist and return an automationId or clearly report that user action is required.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100