Windows on ARM64: Claude managed agents fail every session/new with -32603 (win-x64 Node provisioned on ARM64 host; error.data dropped from logs)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
On Windows 11 ARM64, every Claude-backed managed agent fails every room mention with:
```
Agent reported error (code -32603): Internal error
```
while OpenAI-backed managed agents in the same room work normally. Two separate defects combine here:
1. **Buzz provisions a win-x64 Node runtime on ARM64 hosts**, which breaks architecture-sensitive native-binary resolution inside Node-based ACP adapters (`@agentclientprotocol/claude-agent-acp`).
2. **`buzz-acp` discards the JSON-RPC `error.data` payload when logging agent errors**, which hid the adapter's fully actionable error message, making this look like an opaque Claude failure.
## Environment
- Windows 11 Home ARM64 (10.0.26200) — Snapdragon-class machine
- Buzz desktop 0.5.3 (x64 build, running under Windows x64 emulation)
- `@agentclientprotocol/claude-agent-acp` 0.64.0, installed into the global npm prefix using the system **arm64** Node v24.8.0 / npm
- Claude Code CLI 2.1.220, claude.ai subscription auth (`claude auth status` healthy)
- Buzz-managed Node runtime: `%APPDATA%\Buzz\runtimes\node\v24.18.0\win-x64\node.exe` (PE header: x64)
## Root cause chain
1. `buzz-desktop.exe` and `buzz-acp.exe` are x64 binaries. On an ARM64 host they run under emulation, and `managed_node_paths.rs` selects the Node platform via `std::env::consts::ARCH` — a **compile-time** constant that is `"x86_64"` inside an x64 build regardless of the real machine. So Buzz provisions **win-x64** Node. (The `("windows", "aarch64") => ("win-arm64", ...)` arm added on `main` can never be taken by an x64-built binary.)
2. The npm shim `claude-agent-acp.cmd` resolves `node` from `PATH`; under Buzz that is the bundled win-x64 Node, so the adapter runs with `process.arch === "x64"`.
3. On `session/new`, the adapter's `claudeCliPath()` resolves the SDK CLI as `@anthropic-ai/claude-agent-sdk-win32-x64/claude.exe`. Because the adapter was installed by an **arm64** npm, only `@anthropic-ai/claude-agent-sdk-win32-arm64` is vendored. Resolution fails and the adapter throws:
> Claude native binary not found for win32-x64. Reinstall @anthropic-ai/claude-agent-sdk without --omit=optional, or set CLAUDE_CODE_EXECUTABLE.
4. The ACP TypeScript SDK wraps this plain exception as `{ code: -32603, message: "Internal error", data: { details: "" } }`.
5. `agent_error_from_json` in `crates/buzz-acp/src/acp.rs` keeps only `code` and `message` whenever `message` is a string — `error.data` is dropped, so the actionable text in step 3 never appears in any Buzz log. Operators see only a generic `agent_returned … error=Agent reported error (code -32603): Internal error`.
Because the failure is thrown before the CLI is ever spawned, no amount of model-id, parallelism, or permission-mode configuration changes the outcome — which cost us several hours of ruling those out.
## Reproduction (standalone, no Buzz needed)
Pipe ACP over stdio into the adapter, once under each Node:
```
initialize {"protocolVersion":2, "clientInfo":{"name":"buzz-acp","version":"0.5.3"}, ...}
session/new {"cwd":"", "mcpServers":[], "_meta":{"sessionTitle":"repro"}}
```
| Adapter launched under | session/new result |
|---|---|
| Buzz-bundled win-x64 Node v24.18.0 | `-32603 Internal error`, `data.details` = "Claude native binary not found for win32-x64…" |
| System arm64 Node v24.8.0 | success |
| win-x64 Node + `CLAUDE_CODE_EXECUTABLE` → the vendored win32-arm64 `claude.exe` | success |
## Workaround (confirmed working)
Add to the Claude agents' `env_vars` in `managed-agents.json`:
```json
"env_vars": {
"CLAUDE_CODE_EXECUTABLE": "C:\\Users\\\\AppData\\Roaming\\npm\\node_modules\\@agentclientprotocol\\claude-agent-acp\\node_modules\\@anthropic-ai\\claude-agent-sdk-win32-arm64\\claude.exe"
}
```
The x64-emulated adapter process spawns the ARM64 CLI without issue.
## Suggested fixes
1. **Runtime arch detection for the managed Node runtime** — decide win-x64 vs win-arm64 from the *OS* architecture at runtime (e.g. `IsWow64Process2`, or Rust: checking `PROCESSOR_ARCHITEW6432`/`RuntimeInformation`-equivalent), not `std::env::consts::ARCH`; or ship a native ARM64 build of Buzz.
2. **Stop dropping `error.data`** — `agent_error_from_json` should append `data` (or at least `data.details`) to the logged message when present. The adapter had put the exact remedy on the wire; Buzz logged "Internal error".
Possibly related in spirit but distinct from #2698 / #2692 (those are model-picker issues; this fails before any model is reached).
## Also affected
The bundled Claude installer flow has the same arch blindness: `install-claude.log` on this machine shows Buzz fetching `claude-2.1.220-win32-x64.exe`, which then crashed with `0xC0000005` on the ARM64 host.
Contributor guide
Assessment
This issue has not been assessed yet.