[BUG] Windows ARM64 desktop app keeps spawning cached x64 CLI (0xC0000005 under Prism); locked binary makes arch swap fail silently

Open 💬 0 comments Opened Jul 10, 2026 by KBenMcDova

Summary

On Windows ARM64 (Snapdragon), the desktop app's CLI preflight only checks for a .verified marker — it never validates the cached binary's architecture. After upgrading from the x64 desktop app to the native ARM64 build, the app silently keeps spawning the previously cached win32-x64 Bun CLI under Prism emulation, which crashes intermittently with 0xC0000005 (STATUS_ACCESS_VIOLATION). When the app does attempt to reinstall, the swap fails silently because the running x64 CLI locks claude.exe, leaving a .zst.partial and a resume-retry loop that never completes.

The result for the user: "Claude Code process exited with code 3221225477" randomly on session start/resume, persisting even after installing the correct ARM64 app.

Environment

  • Device: Microsoft Surface Laptop, 7th Edition (Snapdragon, ARM64)
  • OS: Windows 11 Pro, build 26200 (25H2)
  • Desktop app: 1.20186.0 — initially x64 build, later replaced with native ARM64 (MSIX Claude_1.20186.0.0_arm64)
  • CLI: 2.1.205 at %APPDATA%\Claude\claude-code\2.1.205\claude.exe
  • win32-arm64 is present in the 2.1.205 release manifest, so a native binary was available the whole time

Timeline / evidence (from %APPDATA%\Claude\logs\main.log)

  1. With the x64 app installed (worst case — everything emulated): intermittent 0xC0000005 since 2026-07-08, across CLI 2.1.202 and 2.1.205 and app 1.19367.0 → 1.20186.0. Crashes hit both session resume and bare "temporary query" startup (Failed to get commands from temporary query), i.e. not content-related. A RADAR_PRE_LEAK_64 WER event was also recorded against claude.exe. No crash dumps are ever produced — the Bun panic handler swallows the exception, so WER LocalDumps never fires and the only artifact is the exit code.
  1. After installing the native ARM64 desktop app: crashes continue identically, because the app still spawns the cached x64 CLI:
2026-07-10 16:38:34 [info] Using Claude Code binary at: C:\Users\...\AppData\Roaming\Claude\claude-code\2.1.205\claude.exe   <- PE machine type 0x8664 (x64)
2026-07-10 16:38:46 [error] Session ... query error: Claude Code process exited with code 3221225477
  1. The app then re-downloads (correctly sized for a different platform: 57,260,419 bytes vs the original x64 59,562,945), but cannot install it while any claude.exe is alive — the target file is locked. It silently loops:
2026-07-10 16:46:20 [info] [CCD] Downloaded 57260419 bytes
2026-07-10 16:46:21 [info] [CCD] Downloaded 57260419 bytes (resumed from 57260419)
2026-07-10 16:46:23 [info] [CCD] Downloaded 57260419 bytes (resumed from 57260419)
...

leaving download.<hash>.zst.partial next to the stale x64 claude.exe + .verified. No user-visible error; preflight keeps accepting the x64 binary because .verified exists:

2026-07-08 11:14:02 [info] [CCD] Binary preflight: .verified missing but download in flight — awaiting

Workaround that fixed it

  1. Delete %APPDATA%\Claude\claude-code\<version>\.verified
  2. Fully quit the app (tray → Quit) so nothing holds a lock on claude.exe
  3. Relaunch — the ARM64 app now downloads and installs the win32-arm64 binary (confirmed via PE header: machine 0xAA64)

All crashes stopped once the CLI was native.

Suggested fixes

  • Binary preflight should compare the cached binary's PE machine type against process.arch (or record the platform key in .verified) and treat an architecture mismatch as "not installed". This mirrors the macOS-flavored reports in #13617 / #22117 where an x86_64 binary ends up running under translation on ARM hardware.
  • The installer should handle the locked-target case explicitly (staged install + swap on next start, and/or surface an error) instead of silently retry-looping on the completed download.
  • Consider having the x64 desktop installer warn on ARM64 hosts (IsWow64Process2 reports the machine correctly even under emulation) — running the whole stack under Prism is what exposes the Bun JIT 0xC0000005 crashes in the first place.

🤖 Generated with Claude Code

View original on GitHub ↗