Summary
When running Cyrus on Ubuntu/WSL2 (glibc), the bundled @anthropic-ai/claude-agent-sdk resolves to its musl-linked binary at runtime and fails with "Claude Code native binary not found." Both platform variants are installed in node_modules, but the SDK picks the wrong one for the host libc.
Environment
- OS: Ubuntu 24.04.3 LTS (Noble Numbat) on WSL2
- Kernel:
6.6.114.1-microsoft-standard-WSL2
- libc: GLIBC 2.39
- Arch: x86_64
- Node: v20.19.6
- Package manager: yarn classic (used by Cyrus install)
- Cyrus: 0.2.57
@anthropic-ai/claude-agent-sdk: 0.2.123
claude CLI installed separately at ~/.local/bin/claude (v2.1.150)
Symptom
[ERROR] [EdgeWorker] {session=…, platform=linear, issue=BUM-56} Session error:
ReferenceError: Claude Code native binary not found at
/.config/yarn/global/node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl/claude.
Please ensure Claude Code is installed via native installer or specify a valid path
with options.pathToClaudeCodeExecutable.
at ChildProcess.<anonymous> (file://…/claude-agent-sdk/sdk.mjs:59:7871)
The error is misleading — the binary is present at that path, it just can't execute on glibc because it's musl-linked.
Root cause
Both platform-specific optional dependencies are installed:
@anthropic-ai/claude-agent-sdk-linux-x64 (declares "libc": ["glibc"])
@anthropic-ai/claude-agent-sdk-linux-x64-musl (declares "libc": ["musl"])
file on each binary confirms:
linux-x64-musl/claude: ELF 64-bit LSB executable, x86-64, … interpreter /lib/ld-musl-x86_64.so.1
linux-x64/claude: ELF 64-bit LSB executable, x86-64, … interpreter /lib64/ld-linux-x86-64.so.2 (glibc)
The musl-linked binary cannot execute on a glibc host, so any attempt to spawn it produces the error above.
package.json metadata is correct on both variants — the bug is in the SDK's runtime libc detection, which selects the musl variant on a glibc host. Likely cause is yarn classic installing both optional deps because it doesn't enforce the libc filter at install time (only os and cpu), leaving runtime resolution to choose — and the SDK choosing wrong.
Workaround
Symlink the musl path to the glibc binary so the SDK's wrong choice resolves to the working binary:
cd ~/.config/yarn/global/node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl
mv claude claude.musl.broken.bak
ln -sf ../claude-agent-sdk-linux-x64/claude claude
This gets overwritten on cyrus updates that touch the SDK and needs re-applying.
Suggested fixes
In rough order of cleanliness:
- In
@anthropic-ai/claude-agent-sdk runtime resolution: detect host libc via process.report.getReport().header.glibcVersionRuntime (or detect-libc) and pick the matching variant explicitly instead of relying on package-manager filtering.
- In Cyrus's install path: depending on host libc, install only the matching SDK variant (
--ignore-optional + targeted install).
- Documentation: add a troubleshooting entry for this symptom + the symlink workaround.
Happy to PR (3) immediately if useful. (1) is the proper fix but belongs upstream in the SDK.
Related
- Surfaces on every fresh Cyrus install I've tried on WSL2 Ubuntu.
- Doesn't affect setups where
claude is invoked via pathToClaudeCodeExecutable pointing at a separately-installed Claude Code binary — but Cyrus's default config doesn't expose that field.
Summary
When running Cyrus on Ubuntu/WSL2 (glibc), the bundled
@anthropic-ai/claude-agent-sdkresolves to its musl-linked binary at runtime and fails with "Claude Code native binary not found." Both platform variants are installed innode_modules, but the SDK picks the wrong one for the host libc.Environment
6.6.114.1-microsoft-standard-WSL2@anthropic-ai/claude-agent-sdk: 0.2.123claudeCLI installed separately at~/.local/bin/claude(v2.1.150)Symptom
The error is misleading — the binary is present at that path, it just can't execute on glibc because it's musl-linked.
Root cause
Both platform-specific optional dependencies are installed:
@anthropic-ai/claude-agent-sdk-linux-x64(declares"libc": ["glibc"])@anthropic-ai/claude-agent-sdk-linux-x64-musl(declares"libc": ["musl"])fileon each binary confirms:The musl-linked binary cannot execute on a glibc host, so any attempt to spawn it produces the error above.
package.jsonmetadata is correct on both variants — the bug is in the SDK's runtime libc detection, which selects the musl variant on a glibc host. Likely cause is yarn classic installing both optional deps because it doesn't enforce thelibcfilter at install time (onlyosandcpu), leaving runtime resolution to choose — and the SDK choosing wrong.Workaround
Symlink the musl path to the glibc binary so the SDK's wrong choice resolves to the working binary:
This gets overwritten on
cyrusupdates that touch the SDK and needs re-applying.Suggested fixes
In rough order of cleanliness:
@anthropic-ai/claude-agent-sdkruntime resolution: detect host libc viaprocess.report.getReport().header.glibcVersionRuntime(ordetect-libc) and pick the matching variant explicitly instead of relying on package-manager filtering.--ignore-optional+ targeted install).Happy to PR (3) immediately if useful. (1) is the proper fix but belongs upstream in the SDK.
Related
claudeis invoked viapathToClaudeCodeExecutablepointing at a separately-installed Claude Code binary — but Cyrus's default config doesn't expose that field.