Short description
onnxruntime-node native binding fails to load on Alpine (musl). Plugin should fall back to the WASM runtime it already uses for Electron instead of disabling local embeddings.
What happened?
On Alpine Linux (musl libc), embedding.provider: "local" fails because onnxruntime-node ships only glibc prebuilt binaries. The plugin already detects this exact failure via isNativeRuntimeMissingError() and — instead of falling back to the WASM runtime it already uses for Electron — simply disables local embeddings.
Environment:
- OS: Alpine Linux (Docker), official image
ghcr.io/anomalyco/opencode:latest
- libc: musl (no
__vsnprintf_chk)
- Node.js: v24.18.1
- opencode: 1.18.19
- magic-context: v0.40.0
- Note: the attached diagnostic report was captured with
embedding.provider: "off" (the current workaround). The bug reproduces by setting embedding.provider: "local".
Error (doctor --harness opencode):
Embedding provider: local — onnxruntime-node native binding missing —
binding failed to load: ERR_DLOPEN_FAILED: Error relocating
.../onnxruntime-node/bin/napi-v6/linux/x64/libonnxruntime.so.1:
__vsnprintf_chk: symbol not found
Root cause:
__vsnprintf_chk is glibc-specific; Alpine's musl does not provide it, so dlopen() of the native libonnxruntime.so.1 fails. Upstream has no musl prebuilt: microsoft/onnxruntime#9483.
What the code already does:
embedding-local.ts already injects the WASM runtime via injectWasmOrtForElectron() (guarded by process.versions?.electron) and detects this exact failure via isNativeRuntimeMissingError(). So detection is present, but the response is "disable" rather than "use WASM".
Steps to reproduce
- docker run -it ghcr.io/anomalyco/opencode:latest
- Set embedding.provider: "local" in magic-context.jsonc
- Run: npx @cortexkit/magic-context@latest doctor --harness opencode
- Observe ERR_DLOPEN_FAILED: __vsnprintf_chk: symbol not found
Proposed change
When isNativeRuntimeMissingError() fires on a non-Electron runtime (musl/Alpine), fall back to the existing WASM injection instead of disabling local embeddings.
Related
Diagnostics
magic-context-issue-20260824-182207-full.md
Plugin version
v0.40.0
OpenCode version
1.18.19
Platform
Alpine Linux (Docker) — musl libc
Client
OpenCode web UI (browser, via serve on Docker)
Short description
onnxruntime-node native binding fails to load on Alpine (musl). Plugin should fall back to the WASM runtime it already uses for Electron instead of disabling local embeddings.
What happened?
On Alpine Linux (musl libc),
embedding.provider: "local"fails becauseonnxruntime-nodeships only glibc prebuilt binaries. The plugin already detects this exact failure viaisNativeRuntimeMissingError()and — instead of falling back to the WASM runtime it already uses for Electron — simply disables local embeddings.Environment:
ghcr.io/anomalyco/opencode:latest__vsnprintf_chk)embedding.provider: "off"(the current workaround). The bug reproduces by settingembedding.provider: "local".Error (
doctor --harness opencode):Embedding provider: local — onnxruntime-node native binding missing —
binding failed to load: ERR_DLOPEN_FAILED: Error relocating
.../onnxruntime-node/bin/napi-v6/linux/x64/libonnxruntime.so.1:
__vsnprintf_chk: symbol not found
Root cause:
__vsnprintf_chkis glibc-specific; Alpine's musl does not provide it, sodlopen()of the nativelibonnxruntime.so.1fails. Upstream has no musl prebuilt: microsoft/onnxruntime#9483.What the code already does:
embedding-local.tsalready injects the WASM runtime viainjectWasmOrtForElectron()(guarded byprocess.versions?.electron) and detects this exact failure viaisNativeRuntimeMissingError(). So detection is present, but the response is "disable" rather than "use WASM".Steps to reproduce
Proposed change
When
isNativeRuntimeMissingError()fires on a non-Electron runtime (musl/Alpine), fall back to the existing WASM injection instead of disabling local embeddings.Related
Diagnostics
magic-context-issue-20260824-182207-full.md
Plugin version
v0.40.0
OpenCode version
1.18.19
Platform
Alpine Linux (Docker) — musl libc
Client
OpenCode web UI (browser, via serve on Docker)