[BUG] Silent npm→native auto-migration writes autoUpdatesChannel: "stable" and downgrades the CLI (2.1.220 → 2.1.212), removing new models from /model

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Jul 29, 2026

Summary

The background auto-updater performed a silent npm → native migration during a running session and, as a side effect, (1) wrote "autoUpdatesChannel": "stable" into ~/.claude/settings.json without any notice, (2) removed the npm-installed CLI (which was on 2.1.220), and (3) installed the older stable release 2.1.212 — an effective downgrade that removed access to newly released models (Claude Opus 5 disappeared from /model).

Because settings.json is a file many users sync between machines (dotfile syncs, our own settings sync), the silently injected "stable" flag then propagated to a second machine, whose auto-updater obediently downgraded it too (2.1.220 → 2.1.212). Net effect: a fleet-wide, unattended downgrade with no log line, no notice, and a confusing user experience ("the model I used yesterday is gone").

Environment

  • macOS 26.5 (Darwin 25.5.0), two Macs (Mac Studio + MacBook)
  • Claude Code native install in ~/.local/share/claude/versions/, plus a leftover npm-global install (nvm) on the MacBook
  • Timezone MDT (UTC−6); timestamps below are local unless marked UTC

Evidence timeline (from disk artifacts)

  1. Jul 25, 21:35 — MacBook auto-update via npm path, ~/.claude/.last-update-result.json:

``json
{"timestamp":"2026-07-26T03:35:37.137Z","path":"npm-global","outcome":"success","status":"success","version_from":"2.1.208","version_to":"2.1.220","error_code":null}
`
Opus 5 available in
/model` from here on.

  1. Jul 27, 19:49 — during an ordinary running session (session transcript contains no install/update commands; shell history clean; no LaunchAgent involved), the auto-updater migrated npm → native:
  • npm package removed: ~/.nvm/versions/node/v24.14.1/lib/node_modules/@anthropic-ai/ is now empty, dir mtime Jul 27 19:49
  • native stable installed: ~/.local/share/claude/versions/2.1.212 created Jul 27 19:49
  • "autoUpdatesChannel": "stable" appeared in ~/.claude/settings.json (captured by our settings-sync git history at 2026-07-28T02:18Z, absent in the previous snapshot 30 min earlier)
  1. Jul 28, 13:12 — second machine (Mac Studio, native install, previously auto-updating on latest: 2.1.214 → 2.1.217 → 2.1.219 → 2.1.220 per versions/ dir timestamps) received the synced "stable" flag and its auto-updater downgraded:

``json
{"timestamp":"2026-07-28T19:12:52.767Z","path":"native","outcome":"success","status":"success","version_from":"2.1.220","version_to":"2.1.212","error_code":null}
`
Result: Opus 5 gone from
/model` on both machines.

Why this matters beyond a version number

  • The downgrade silently removed access to a just-released model tier. Users can't tell whether the model was pulled server-side, their account changed, or their client regressed — it looks like data/feature loss.
  • A background process mutating user settings (autoUpdatesChannel) without notice interacts badly with any settings-sync setup, turning a single-machine side effect into a multi-machine downgrade.
  • If a future stable→latest gap contains security or data-integrity fixes, the same silent channel switch would roll those back too.

Expected behavior

  • npm → native migration should preserve the currently installed version and effective channel (npm installs track latest; migrating to native stable + older binary is a downgrade, not a migration).
  • Any write to settings.json by the updater should be surfaced to the user (message in-session, log line, changelog entry) — ideally not happen at all without consent.
  • The updater should never move to a lower version than currently active without an explicit user action, or at minimum should print/notify that a downgrade occurred and why.

Repro sketch

  1. Have both an npm-global (@anthropic-ai/claude-code at a recent latest) and conditions for native migration on macOS.
  2. Run an ordinary interactive session and let the background updater trigger the npm → native migration.
  3. Observe: npm package removed, native stable (older) installed and activated, "autoUpdatesChannel": "stable" written into ~/.claude/settings.json with no user-visible notice; newer-model entries disappear from /model.

Related (adjacent, not duplicate): #69319 — claude update checks "stable" despite autoUpdatesChannel: "latest". Together they suggest channel handling in the native updater needs a review.

Recovery that worked for us, for anyone else hitting this: claude install latest, then delete the autoUpdatesChannel key from ~/.claude/settings.json (absent key = latest), on every affected machine.

View original on GitHub ↗