Skip to content

Desktop auto-update installed an ARM64 AppImage on an x86_64 machine - app refuses to start after updating to 0.0.87 #1277

Description

@brockenlesnair

Moved from CodebuffAI/codebuff-community#14 — originally filed there by mistake (this is a Freebuff product issue).

Desktop auto-update installed an ARM64 build on an x86_64 machine — app then refused to start

Product: Freebuff Desktop (Linux AppImage)
Versions: prior install (older) → 0.0.87 (arm64 artifact wrongly applied to an x86_64 host)
Type: Bug / updater safety (wrong-architecture update applied with no validation)
Severity: High for affected users (app becomes completely unable to start; no error surfaced by the updater)

Summary

On an x86_64 Linux machine, Freebuff Desktop auto-updated itself from an older version to 0.0.87 (confirmed by the user: the running app downloaded and applied the update). The updater replaced the running binary with the linux-arm64 0.0.87 AppImage instead of the x86_64 one. The file was byte-identical in size (161,915,176 B) to the official Freebuff-0.0.87-linux-arm64.AppImage asset and its content was aarch64 ELF (AppImage runtime and bundled resources/bun/bun). Because the host is x86_64, every launch after the update failed immediately with Exec format error (AppImageLauncher: failed to execute patched runtime: Exec format error). The app only recovered after manually replacing the file with the correct x86_64 asset.

The updater performed the in-place replacement preserving the old filename (Freebuff-0.0.18-linux-x86_64_<hash>.AppImage) — classic electron-updater AppImage behavior (download → rename over the current executable). That is why the surviving filename looks x86_64 while the content is ARM: the name is the old build's name, the content is the new (wrong-arch) build.

Environment

  • OS: Linux (Ubuntu 24.04 base), kernel 7.0.0-28-generic, GNOME/Wayland
  • CPU: Intel Core i5-6300U (x86_64)
  • AppImageLauncher 3.0.0-beta-2
  • Freebuff Desktop 0.0.87 AppImage (app package @codebuff/freebuff-desktop)

Timeline (local time, UTC+3)

When (local) Event
2026-09-04 00:04 Older-version app launches and runs normally (orchestrator-stderr.log written); app config dir active
00:06 Auto-update to 0.0.87 replaces the running AppImage in place (same filename) with the arm64 artifact; config writes stop as the app quits to finish updating
00:06 onward Every launch fails: Exec format error (aarch64 ELF on x86_64 host)
01:05 (after manual fix) App runs again from the official Freebuff-0.0.87-linux-x86_64.AppImage; updater reports 0.0.87 current, no pending update

The 0.0.87 release assets/tag: manifests dated 2026-09-04T07:46 UTC, GitHub tag freebuff-desktop-v0.0.87 published 2026-09-04T08:13 UTC (asset upload window ~07:46–08:13 UTC).

Evidence

  • Broken on-disk file size 161,915,176 B == exactly the size the arm64 channel manifest advertises for Freebuff-0.0.87-linux-arm64.AppImage (the x64 asset is 161,441,297 B).
  • file on the broken AppImage: ELF 64-bit LSB pie executable, ARM aarch64; resources/bun/bun: ELF 64-bit LSB executable, ARM aarch64.
  • Broken file's resources/app-update.yml (read via direct squashfs extraction): provider: generic, url: https://freebuff.com/api/desktop/updates/linux-arm64/.
  • Filename retained from the older install (Freebuff-0.0.18-linux-x86_64_….AppImage) while content is 0.0.87-arm64 → in-place overwrite by the updater, not a fresh manual download (no matching downloaded file exists anywhere; no updater cache leftovers).
  • After fix, installed x64 file sha512 matches the linux-x64 channel manifest; updater confirms current.

Current channel state (checked 2026-09-05) — both correct

Channel Manifest advertises size
…/updates/linux-x64/latest-linux.yml Freebuff-0.0.87-linux-x86_64.AppImage 161,441,297 B
…/updates/linux-arm64/latest-linux-arm64.yml Freebuff-0.0.87-linux-arm64.AppImage 161,915,176 B

The previous x64 release was also checked: Freebuff-0.0.86-linux-x86_64.AppImage ships the correct linux-x64 channel in its app-update.yml (and its inner bun is x86-64). So neither the current channels nor the immediately previous build are statically misconfigured today.

Root-cause assessment

Confirmed:

  1. The trigger was the app's own auto-updater (user-confirmed; consistent with all file evidence).
  2. The updater on the x86_64 client downloaded and installed the arm64 0.0.87 artifact with no architecture validation, then replaced the running binary in place.

Most likely mechanism (in order of probability):

  1. Transient channel/manifest mixup at publish time. The x64 client fetched the 0.0.87 update from a channel/manifest that advertised (or served) the arm64 file — e.g. during the 07:46–08:13 UTC asset-upload window, or via a caching/proxy layer that served the arm64 manifest for the x64 channel. Channels are correct now, which is why this has to be reconstructed from the timeline rather than reproduced live.
  2. Outdated/mispointed app-update.yml in the specific older build that was installed (older than v0.0.86, which we verified is correct). The installed build's wrapper version predates the current linux-x64 channel naming (filename version 0.0.18), so it may have pointed at a channel path that later became the arm64 channel.

Either mechanism is only survivable because of the missing safety checks below.

Safety gaps (the actionable part for the team)

  1. No architecture check before applying an update. The updater trusts the channel manifest's filename and never inspects the ELF header of the artifact it installs. One ELF-magic/process.arch check before replacing the running binary would have prevented this entire incident.
  2. Version-only update gate. The updater only compares semantic versions ("downgrade is disallowed" was the only message after the fix). A same-version, different-architecture artifact can silently overwrite a working install — or, as here, an upgrade can cross architectures.
  3. In-place replace with no rollback. When the newly installed AppImage fails to exec (ENOEXEC/Exec format error), there is no fallback to the previous working binary and no error surfaced to the user beyond "the app won't start".
  4. No channel↔arch parity verification in publishing. Nothing asserts that the artifact referenced by the linux-x64 channel is actually x86-64 (and vice versa) before the channel goes live.

Suggested fixes

  • Client (blocking): Validate architecture of the downloaded AppImage (ELF machine type of the runtime and of key inner binaries such as resources/bun/bun) against the running platform; refuse to install on mismatch and keep the previous binary.
  • Client: Include arch/target in the update gate (same version + different arch must not be treated as a no-op/downgrade).
  • Client: On next-launch exec failure after an update, roll back to the retained previous AppImage and surface a diagnostic.
  • Publishing/CI: Verify per-channel manifests reference artifacts whose architecture matches the channel; add a post-publish check that /api/desktop/updates/linux-x64/latest-linux.yml and /api/desktop/download/linux point at x86-64 assets and the arm64 equivalents point at aarch64 assets.

Workaround (for affected users)

# verify before trusting any download
curl -L -o Freebuff-x64.AppImage "https://freebuff.com/api/desktop/download/linux"
file Freebuff-x64.AppImage    # must say: ELF … x86-64  (aarch64/arm64 ⇒ wrong file)
# replace the broken AppImage in ~/Applications and relaunch

Related links

  • Release assets: github.com/CodebuffAI/codebuff-community/releases (tags freebuff-desktop-v0.0.86, freebuff-desktop-v0.0.87)
  • Repo referenced by the npm CLI package: github.com/CodebuffAI/freebuff-private

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:desktopThe Electron desktop appbot:triagedClassified by the community triage bottype:bugA defect in the code with a reproducible failure

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions