Automation created with status PAUSED is silently saved as ACTIVE

Open
#36,256 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
rust
Domain
tooling

Research direction

Start at the automation_update entry point for mode=create and compare its status handling with mode=update. Inspect the persisted ~/.codex/automations//automation.toml using the PAUSED reproduction in the issue. Done means creating with status PAUSED preserves status = "PAUSED" and does not report silent success when it cannot.

Written by the indexing model from the issue text.

Description

app automations bug
Summary

When creating a Codex Desktop automation through the app's automation_update tool with mode: "create" and status: "PAUSED", the call reports success but the saved automation.toml records status = "ACTIVE". The requested status is silently dropped, so the automation is scheduled and will fire even though the caller asked for it to be created paused.

The same field works correctly on mode: "update", which makes this specifically a create-path bug rather than a general status-handling problem.

Reproduction

Run 1 — create with status: "PAUSED":

{
  "mode": "create",
  "kind": "cron",
  "name": "Repro probe A (prompt persistence test)",
  "prompt": "MARKER_VERSION_ONE: ...",
  "rrule": "FREQ=DAILY;BYHOUR=4;BYMINUTE=30;BYSECOND=0",
  "model": "gpt-5.5",
  "reasoningEffort": "medium",
  "executionEnvironment": "local",
  "projectId": "local-<redacted>",
  "status": "PAUSED"
}

Tool result: Created automation in the app. with {"automationId":"repro-probe-a-prompt-persistence-test","mode":"create"}

Saved ~/.codex/automations/repro-probe-a-prompt-persistence-test/automation.toml:

version = 1
id = "repro-probe-a-prompt-persistence-test"
kind = "cron"
name = "Repro probe A (prompt persistence test)"
prompt = "MARKER_VERSION_ONE: ..."
status = "ACTIVE"          # <-- requested PAUSED
rrule = "FREQ=DAILY;BYHOUR=4;BYMINUTE=30;BYSECOND=0"
model = "gpt-5.5"
reasoning_effort = "medium"
execution_environment = "local"
created_at = 1785467926206
updated_at = 1785467926206

Run 2 — confirm it is not a one-off, with a different id and schedule:

{
  "mode": "create",
  "kind": "cron",
  "name": "Repro probe B (created paused)",
  "prompt": "PROBE_B: created with status PAUSED to check whether the requested status is honored at creation time.",
  "rrule": "FREQ=DAILY;BYHOUR=4;BYMINUTE=35;BYSECOND=0",
  "status": "PAUSED"
}

Saved file again shows status = "ACTIVE" with created_at == updated_at, so nothing overwrote it after the fact.

Run 3 — same field via mode: "update" on the existing automation:

{ "mode": "update", "id": "repro-probe-a-prompt-persistence-test", "status": "PAUSED", ... }

Saved file correctly shows:

prompt = "MARKER_VERSION_THREE: testing whether an explicit PAUSED status persists on update."
status = "PAUSED"
updated_at = 1785467966071

So PAUSED round-trips on update and is dropped on create.

Expected behavior

mode: "create" with status: "PAUSED" should persist status = "PAUSED", matching mode: "update". If a paused automation cannot be created for some reason, the tool should return an explicit error or a warning naming the coerced field rather than reporting plain success.

Impact

The failure is silent, which is the main problem. A caller that creates a paused automation intending to review or edit it before enabling it instead gets a live schedule. For a daily rrule this means an unintended run at the next matching time. Because the tool result says Created automation in the app. with no mention of the coercion, the only way to notice is to read the saved TOML by hand after every create.

Notes on a related observation

While investigating, I hit repeated cases where mode: "update" returned success but a prompt edit did not appear in the saved TOML, and where a regenerated prompt appeared to revert to an earlier version. Editing the TOML by hand did not stick either; the app rewrote the previous value shortly after. I could not reduce that to a reliable reproduction in this session — the prompt-update path worked correctly in every controlled attempt above (MARKER_VERSION_ONETWOTHREE all persisted). I mention it only as context in case it shares a code path with the create-status coercion. The status bug above is the reproducible part.

One additional API-shape note: mode: "update" rejects partial payloads. Sending only {mode, id, prompt} fails validation with name: Invalid input: expected string, received undefined; rrule: ...; status: ...; projectId: ...; model: ...; reasoningEffort: ...; executionEnvironment: ..., so every field has to be resupplied. That makes a read-modify-write cycle mandatory for a one-field change, and any field the caller reconstructs incorrectly becomes a silent overwrite of the stored value.

Environment
  • macOS 26.5.2 (build 25F84), Apple silicon
  • codex-cli 0.144.4
  • Codex Desktop app, automations stored under ~/.codex/automations/
  • Automation kind: cron, execution_environment = "local", project target
Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

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.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.