The static grounding sweep on docs/compat-matrix flagged S26 ("auto-update doesn't fire / corrupt the install") as Missing in build 1.5354.0. Writing it up here so we can pick a fix before it bites us.
What I found
The autoUpdater gate inside the bundled app is structurally open on Linux when app.isPackaged is true:
lii() at build-reference/app-extracted/.vite/build/index.js:508761-508774 returns true on Linux when the app is packaged.
- The truthy path sets the autoUpdater feed URL to
api.anthropic.com/api/desktop/linux/... and registers update-check listeners.
- Our launcher exports
ELECTRON_FORCE_IS_PACKAGED=true at scripts/launcher-common.sh:249, so app.isPackaged is true on every install we ship — deb, rpm, AppImage, AUR.
The only reason this doesn't actually try to download anything today is that Electron's Linux autoUpdater is unimplemented. It logs AutoUpdater is not supported on Linux and no-ops. That's a happy accident. If a future Electron bump implements Linux auto-update, or upstream switches to electron-updater, every install in the wild will start hitting that Linux feed URL — and upstream doesn't ship Linux binaries through their feed. Best case: 404s on every check. Worst case: serves something that doesn't match what we shipped, which our installs aren't prepared for.
Case doc with the full anchor list: docs/testing/cases/distribution.md S26.
Two fixes I see
Option 1 — Wrap hA.autoUpdater in frame-fix-wrapper.js to no-op on Linux.
Same pattern as the BrowserWindow defaults override. Smallest diff, lowest risk. Defends against upstream changes regardless of what lii() decides to gate on in a future build.
Option 2 — Gate ELECTRON_FORCE_IS_PACKAGED on the package format in scripts/launcher-common.sh.
Set it true only on AppImage. Leave it unset on deb/rpm where APT/DNF handle updates. More semantically correct — Electron's view of "packaged" lines up with what the user's package manager actually does. Doesn't fix the issue if lii() checks something other than app.isPackaged in a future build.
I'm leaning toward Option 1 because it's defensive and the wrapper already exists for exactly this kind of thing. Option 2 has nicer semantics but a thinner safety margin.
Anyone have a preference, or a third option I'm missing?
Written by Claude opus-4.7 via Claude Code
The static grounding sweep on
docs/compat-matrixflagged S26 ("auto-update doesn't fire / corrupt the install") as Missing in build 1.5354.0. Writing it up here so we can pick a fix before it bites us.What I found
The autoUpdater gate inside the bundled app is structurally open on Linux when
app.isPackagedis true:lii()atbuild-reference/app-extracted/.vite/build/index.js:508761-508774returnstrueon Linux when the app is packaged.api.anthropic.com/api/desktop/linux/...and registers update-check listeners.ELECTRON_FORCE_IS_PACKAGED=trueatscripts/launcher-common.sh:249, soapp.isPackagedis true on every install we ship — deb, rpm, AppImage, AUR.The only reason this doesn't actually try to download anything today is that Electron's Linux
autoUpdateris unimplemented. It logsAutoUpdater is not supported on Linuxand no-ops. That's a happy accident. If a future Electron bump implements Linux auto-update, or upstream switches toelectron-updater, every install in the wild will start hitting that Linux feed URL — and upstream doesn't ship Linux binaries through their feed. Best case: 404s on every check. Worst case: serves something that doesn't match what we shipped, which our installs aren't prepared for.Case doc with the full anchor list:
docs/testing/cases/distribution.mdS26.Two fixes I see
Option 1 — Wrap
hA.autoUpdaterinframe-fix-wrapper.jsto no-op on Linux.Same pattern as the BrowserWindow defaults override. Smallest diff, lowest risk. Defends against upstream changes regardless of what
lii()decides to gate on in a future build.Option 2 — Gate
ELECTRON_FORCE_IS_PACKAGEDon the package format inscripts/launcher-common.sh.Set it true only on AppImage. Leave it unset on deb/rpm where APT/DNF handle updates. More semantically correct — Electron's view of "packaged" lines up with what the user's package manager actually does. Doesn't fix the issue if
lii()checks something other thanapp.isPackagedin a future build.I'm leaning toward Option 1 because it's defensive and the wrapper already exists for exactly this kind of thing. Option 2 has nicer semantics but a thinner safety margin.
Anyone have a preference, or a third option I'm missing?
Written by Claude opus-4.7 via Claude Code