Heartbeat automation update drops model/reasoning_effort and can break scheduled thread delivery

Open 💬 1 comment Opened May 21, 2026 by huymorady

What version of the Codex App are you using (From “About Codex” dialog)?

0.131.0

What subscription do you have?

Pro plan

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

What issue are you seeing?

Updating a heartbeat automation in Codex App causes model and reasoning_effort to be dropped from automation.toml and set to null in codex-dev.db. This happens even when model/reasoningEffort are explicitly included in the update payload.

mode=view does not mutate these fields. Cron automations expose model/reasoning controls in the UI, but heartbeat automations do not, which suggests the heartbeat update serializer may be excluding these fields.

After the fields are nulled, next_run_at may continue advancing, but heartbeat delivery can fail or become unreliable until the metadata is manually restored.

What steps can reproduce the bug?

  1. Create a heartbeat automation attached to an existing Codex App thread with destination="thread".
  2. Confirm the automation has model and reasoning_effort persisted in both:
  • $CODEX_HOME/automations/<automation-id>/automation.toml
  • $CODEX_HOME/sqlite/codex-dev.db, automations row
  1. Run automation_update with mode="view".
  2. Confirm that mode="view" does not mutate automation.toml or the SQLite row.
  3. Run automation_update with mode="update" for the same heartbeat automation, changing only the prompt/instructions.
  4. Observe that model and reasoning_effort are removed from automation.toml and become NULL in codex-dev.db.
  5. Repeat the update while explicitly passing model: "gpt-5.5" and reasoningEffort: "medium".
  6. The update succeeds, but the saved heartbeat automation still drops those fields.
  7. Manually restoring model/reasoning_effort in automation.toml and codex-dev.db makes the heartbeat deliver again.

What is the expected behavior?

Updating a heartbeat automation should preserve existing model and reasoning_effort values unless the user explicitly clears or changes them.

If heartbeat automations intentionally do not support per-automation model/reasoning settings, the update path should not silently null existing stored values, and the UI/tooling should make that behavior explicit.

A successful heartbeat update should not make future scheduled thread delivery unreliable.

Additional information

This appears heartbeat-specific.

Cron automations expose model/reasoning controls in the Desktop UI, while heartbeat automations do not. The heartbeat update path appears to reserialize the automation from a schema that excludes model/reasoning_effort.

Observed behavior:

  • mode="view" is safe and does not mutate metadata.
  • mode="update" on heartbeat drops model/reasoning_effort.
  • Passing model/reasoningEffort explicitly in the update payload does not preserve them.
  • The real heartbeat target_thread_id was non-empty and pointed to an existing, unarchived thread.
  • automation_runs rows may not be a reliable signal for heartbeat-to-thread delivery, since heartbeat messages can be delivered without rows appearing there.

I have redacted local TOML/SQLite evidence and can provide it if needed. I am not attaching raw database files or logs publicly because they may contain personal or sensitive data.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗