[macOS regression] Automatic-update opt-out is overwritten on startup in 26.803.41515

Open 💬 0 comments Opened Aug 8, 2026 by whoschek

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

26.803.41515 (CFBundleVersion 6321)

The installed application is named ChatGPT, with bundle identifier com.openai.codex.

What subscription do you have?

Not relevant to updater behavior / not provided.

What platform is your computer?

Darwin 25.6.0 arm64 arm
macOS 26.6.1 (25G76)

What issue are you seeing?

The macOS app does not preserve an explicit opt-out from automatic updates. Setting Sparkle's persisted automatic-update preference to false is undone shortly after the next app launch:

defaults write com.openai.codex SUAutomaticallyUpdate -bool false
defaults read com.openai.codex SUAutomaticallyUpdate
# 0

After relaunching the app:

defaults read com.openai.codex SUAutomaticallyUpdate
# 1

The raw plist also contains SUAutomaticallyUpdate = true. In the observed launch, the preference plist was rewritten about ten seconds after the app process started. There is no current-host or macOS managed preference supplying the value.

Inspection of this packaged build indicates that startup state received from the renderer controls automatic Sparkle downloads. The main process passes the inverse of a disableSparkleAutodownload gate to the update manager, which then calls the native Sparkle bridge to enable or disable automatic background downloads. This overrides the user's persisted Sparkle choice. The app launch log confirms enableSparkle=true enableUpdater=true.

This appears to regress #18546, which was closed as completed on 2026-08-05 with the statement that the app now exposes an automatic-update checkbox. An explicit user choice must not be overwritten by a remotely supplied default or feature gate.

Impact and severity: Medium, with potentially broad blast radius for macOS users receiving the same update gate. Forced background download/install behavior consumes bandwidth, prevents users from pinning known-good versions, harms reproducibility, and can disrupt managed, SSH, or stability-sensitive workflows. Suggested priority: P2 because a recently delivered explicit opt-out is not durable.

User consent and trust impact

From the affected user's perspective, this behavior is virus-/malware-like: the application downloads and installs executable code on the computer, defeats an explicit local opt-out by rewriting the update preference, and provides no visible automatic-update control in the current UI. Software that changes an administrator-controlled update policy behind the user's back is unacceptable, regardless of vendor intent. It deprives the user of meaningful consent over what executable code runs on their machine and materially damages trust in the application.

Inspection of build 26.803.41515's packaged Settings/UI resources found no automatic-update checkbox or corresponding label. The only related checkbox wording is inside the generic bundled Sparkle framework, while this build uses a custom updater path capable of bypassing that generic prompt. Therefore, the checkbox cited when #18546 was closed is not a reachable persistent setting in this observed current build.

What steps can reproduce the bug?

  1. Fully quit the macOS app.
  2. Set the persisted automatic-update choice to false:

``bash
defaults write com.openai.codex SUAutomaticallyUpdate -bool false
``

  1. Confirm it reads as disabled:

``bash
defaults read com.openai.codex SUAutomaticallyUpdate
# 0
``

  1. Launch the app and wait for startup to complete.
  2. Read the preference again:

``bash
defaults read com.openai.codex SUAutomaticallyUpdate
# 1
``

The issue was observed in build 26.803.41515 / 6321.

What is the expected behavior?

The app should provide and honor persistent update modes such as:

  • automatically download/install;
  • notify only;
  • manual checks only.

Once the user disables automatic updates, neither a startup feature gate nor a server-provided default should set the choice back to true. Remote configuration may establish an initial default only when the user has not made a choice.

Manual update checks should remain available independently of automatic background downloads.

Additional information

Current workaround discovered from the packaged application code:

launchctl setenv CODEX_SPARKLE_ENABLED false

The app recognizes the exact string CODEX_SPARKLE_ENABLED=false and disables Sparkle initialization. This is stronger than necessary, undocumented, and does not inherently persist across logout/reboot. A one-off protected launch is possible with:

open --env CODEX_SPARKLE_ENABLED=false -a ChatGPT

No update was found staged in the Sparkle Installation or PersistentDownloads cache while diagnosing this report.

Known workaround limitations:

  • It disables the updater entirely rather than allowing notify-only behavior.
  • The launch environment must be arranged before the process starts.
  • It is unsuitable as the only control for ordinary users or centrally managed deployments.

Potential fix: treat the renderer/update gate as a default or capability flag, not as the user's preference. Do not call the native automatic-download setter with true on every startup after the user has explicitly opted out. Persist and honor the checkbox added for #18546.

View original on GitHub ↗