[BUG] Auto-update at launch runs for bare `claude` but is skipped when launched with `--effort max`; the flagged session stays on the old version
Preflight Checklist
- [x] I have searched existing issues. Closest: #75607 (CLI self-updated even with
autoUpdates: false), #86244 (a background auto-update invalidates the prompt cache), #91309 (the auto-updater installs a build that cannot launch). None of them is about the auto-update depending on the launch arguments. - [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.258)
What's Wrong?
Native install on macOS (~/.local/bin/claude is a symlink into ~/.local/share/claude/versions/<version>). Auto-update is enabled: DISABLE_AUTOUPDATER is not set, ~/.claude.json has installMethod: "native" and autoUpdatesProtectedForNative: true (it also still carries the legacy autoUpdates: false, which the native updater does not treat as disabled, as the bare launches below show).
Whether the auto-update runs at startup depends on how the CLI is launched:
- Bare
claude: the auto-update runs at startup, no input is accepted until it finishes, and the session comes up on the new version. claude --effort max: the session starts immediately on the installed version, accepts input right away, and does not update. It stays on the old version for its whole lifetime.
Recently I have launched only with --effort max. The install stayed on 2.1.252 (written 2026-08-31T19:51Z) through those daily launches, skipped 2.1.257 (published 2026-09-01T17:15Z) entirely, and only moved to 2.1.258 when I ran bare claude today. An available update is only picked up when I happen to launch without flags.
Today's instance (2026-09-02, times UTC, taken from the files Claude Code writes):
| time | fact |
|---|---|
| 10:57:35 | A session launched with claude --effort max is running on 2.1.252 (every line of its transcript carries "version":"2.1.252"). /model is accepted immediately; no update activity in that session. |
| 10:57:36 | ~/.local/share/claude/versions/2.1.258 is written. |
| 10:57:44 | ~/.claude/cache/changelog.md is rewritten and now starts with ## 2.1.258, i.e. a 2.1.258 process is already running. |
| 10:58:13 | ~/.claude/daemon.log: binary at ~/.local/bin/claude changed (.../versions/2.1.252 → .../versions/2.1.258), shutting down (cause=upgrade, ...), then daemon start version=2.1.258. |
The bare claude launch ran the update at startup and came up on 2.1.258. The claude --effort max session launched in the same minute stayed on 2.1.252.
An update was available to both launches: per the npm registry, 2.1.257 was published 2026-09-01T17:15Z and 2.1.258 at 2026-09-01T22:25Z, both more than 12 hours before these launches (2.1.253 to 2.1.256 were never published). The native latest channel returned 2.1.258 at report time.
What Should Happen?
The startup auto-update should not depend on the launch arguments. claude --effort max should check for and install an update at launch exactly like bare claude does, and a session launched with that flag should at least surface the "Update installed · Restart to apply" notice when a newer version exists, instead of silently staying on the old version.
Error Messages/Logs
No error output. The flagged session showed no update activity at all (no "Checking for updates", "Auto-updating…" or "Update installed" line).
~/.claude/.last-update-result.json keeps only the most recent result. At 11:03:44Z it was overwritten by a separate long-running background session (running on 2.1.251 for three days) that recorded "version_from":"2.1.251","version_to":"2.1.258","outcome":"success" when it was closed, so the record written by the 10:57 install is no longer available.
Steps to Reproduce
- Native install on macOS with auto-update enabled, and a newer version published on the
latestchannel (curl -s https://downloads.claude.ai/claude-code-releases/latestreturns it). - Run
claude --effort max. The session starts immediately on the installed (old) version and no update runs;/statuskeeps showing the old version. - Exit and run bare
claude. The auto-update runs at startup (input is blocked until it finishes) and the session comes up on the new version. - From then on every launch, with or without
--effort max, runs the new version, because the symlink was moved by the bare launch. A--effort maxlaunch never moves it by itself.
Claude Model
claude-fable-5 (not model related)
Is this a regression?
Unknown
Last Working Version
Unknown
Claude Code Version
2.1.258 (the flagged session was on 2.1.252 while the update was available)
Platform
Anthropic (claude.ai account login)
Operating System
macOS 26.5.1 (Darwin 25.5.0), Apple Silicon
Terminal/Shell
zsh, third-party terminal emulator (not the desktop app)
Additional Information
claude --effort maxlaunches made after the symlink had been moved came up on 2.1.258, so the flag does not change which binary is executed; the difference is only that the update step does not run inside a flagged launch.- In the 2.1.258 binary the entry point handles an argv that contains nothing but
--debug*flags on a separate early path beforemainruns, and extracts--effort,--model,--agentand--permission-modeat that same point. That is the only place I could find where a bare launch and a flagged launch diverge; most of the startup code is bytecode inside the binary, so I could not confirm that the startup update step lives there. - Config at report time:
installMethod: "native",autoUpdatesProtectedForNative: true, legacyautoUpdates: false, noDISABLE_AUTOUPDATER/DISABLE_UPDATES/CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICin the environment.stablechannel was 2.1.236,latest2.1.258.