Hit the same symptom on a nightly build, but with a different cause — worth recording here because the fix proposed above wouldn't have cleared it.
My autoUpdatesChannel was already "latest". The mismatch isn't between two channels, it's between two publication pipelines that both call their pointer latest:
| source | value |
|---|---|
npm latest dist-tag — what the advisory reads | 2.1.316 |
GCS claude-code-releases/latest — what claude update follows | 2.1.314 |
| installed | 2.1.314 |
| 1 | $ npm view @anthropic-ai/claude-code dist-tags |
| 2 | { "stable": "2.1.309", "latest": "2.1.316", "next": "2.1.316" } |
| 3 | |
| 4 | $ curl -s .../claude-code-releases/stable # 2.1.308 |
| 5 | $ curl -s .../claude-code-releases/latest # 2.1.314 |
So claude update is behaving correctly — on the latest channel there genuinely is nothing newer than 2.1.314 — and it exits 0. Then runCommandAndVerify re-probes, still sees 2.1.314 < 2.1.316, and returns the message. Permanent loop until the GCS pointer catches up.
T3's own cached advisory (~/.t3/caches/claudeAgent.json):
| 1 | versionAdvisory.status = behind_latest |
| 2 | versionAdvisory.currentVersion = 2.1.314 |
| 3 | versionAdvisory.latestVersion = 2.1.316 |
| 4 | versionAdvisory.updateCommand = ~/.local/bin/claude update |
| 5 | compatibilityAdvisory.status = supported (recommendedRange >=2.1.280) |
Same code path as the original report, at e9a11d4:
- npm
latestfetch —maintenanceResolver.ts:886 - native updater selection —
ClaudeDriver.ts:87-88 - the
stillOutdatedbranch —providerMaintenanceRunner.ts:584-595
Why the channel-mapping fix is incomplete
Mapping autoUpdatesChannel to the matching npm dist-tag fixes the stable case, but not this one: the channel is already latest, and npm latest (2.1.316) still disagrees with GCS latest (2.1.314). Any npm dist-tag is the wrong oracle for a native install, because the native installer doesn't read npm at all. For native installs the comparison wants claude-code-releases/<channel> as its source of truth.
The second suggestion above holds up on its own, and is the cheaper half: when a native update exits 0 and the version is unchanged, treat that as "the update channel has nothing newer" rather than a failure — especially when compatibilityAdvisory.status is already supported, as it was here. Nothing was broken; the banner was the only problem.
Note on the lag
It's a pointer lag, not a missing build — claude-code-releases/2.1.316/manifest.json returns 200 with a full platform set including darwin-arm64, while the latest pointer still reads 2.1.314. claude install 2.1.316 installed cleanly and cleared the advisory. So a user can escape it manually, but only if they know the npm/GCS split exists.
Environment
macOS 27.0.1 (26A434), arm64. T3 Code (Nightly) desktop 0.1.6-nightly.20261030.3940. Claude Code 2.1.314 native (~/.local/bin/claude → ~/.local/share/claude/versions/2.1.314), autoUpdatesChannel: "latest", autoUpdates: false.