openai / openai/codex

Codex App: explicit same-thread heartbeat creation falls back to a non-persistent “Proposed” card after DTSTART validation

Open
#41,483 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app automations bug tool-calls windows-os
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:

  1. The user explicitly asks Codex to create a scheduled task attached to the current chat.
  2. Codex calls automation_update with mode: "create" and an RRULE containing a timezone-specific DTSTART.
  3. The call fails validation and instructs the agent to omit DTSTART or use mode: "suggested_create".
  4. The agent retries with mode: "suggested_create".
  5. The tool returns success and renders a Proposed automation card.
  6. No automation is saved and the chat receives no scheduled-task clock indicator.
  7. A later direct create call without DTSTART saves 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.

  1. Open an existing Codex Desktop chat.

  2. Ask Codex:

    Schedule a deferred task attached to this chat for tomorrow at 2:00 AM.

  3. Observe the initial automation_update call. 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"
    }

  4. 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.

  5. 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"
    }

  6. The tool returns a non-error result containing:
    Rendered automation card in the app.

  7. 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.
  8. 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"
    }

  9. 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:

  1. The task is persisted and the tool returns an automationId; or
  2. 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:

  1. create and suggested_create are exposed as separate tool modes.
  2. The create validator rejects RRULEs containing DTSTART.
  3. Its error text recommends suggested_create for anchored or timezone-specific schedules.
  4. suggested_create is normalized to an internal suggested-create operation.
  5. The persistence handler saves only actual create/update/delete operations.
  6. The suggested-create path renders a proposal card and returns a successful tool result, but does not persist an automation.
  7. The rendered row is labelled Proposed.
  8. 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 Proposed state.

Suggested fixes

Any combination of the following would prevent the failure:

  1. When an explicit create request contains DTSTART, make the preferred recovery path a direct create retry with an equivalent DTSTART-free RRULE.

  2. Only use suggested_create when the user explicitly asked to review a proposal before saving.

  3. Return an explicit structured state for proposals:

    {
    "persisted": false,
    "requiresUserAction": true
    }

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.