Repository navigation
Crash: SIGBUS/SIGTRAP in onnxruntime-node ReleaseIoBinding during local embedding load (concurrent opencode sessions, macOS arm64) #21
Description
Description
Both opencode TUI sessions crash with a native SIGBUS / SIGTRAP inside onnxruntime-node while the magic-context plugin loads the local embedding model (Xenova/all-MiniLM-L6-v2). The crashes occurred in two concurrently-running opencode processes (separate sessions, separate cwd) within seconds of each other — strongly suggests a concurrency / double-free bug in the local embedding loader when two processes touch the same cached model at the same time.
Environment
- Plugin:
@cortexkit/opencode-magic-context@0.9.1 - OpenCode:
1.4.7 - OS:
macOS 26.4.1(build 25E253) - Arch:
arm64(Apple Silicon, M2 Max —Mac14,6) - Node:
v24.15.0 onnxruntime-node:1.21.0(npm) — bundleslibonnxruntime.1.14.0.dylib(native C++ lib)- Transitive dep via:
@huggingface/transformers@~3.7.6
Configuration
~/.config/opencode/magic-context.jsonc:
{
"$schema": "https://raw.githubusercontent.com/cortexkit/opencode-magic-context/master/assets/magic-context.schema.json",
"enabled": true,
"historian": {
"model": "anthropic/claude-haiku-4-5",
"fallback_models": ["opencode-go/glm-5"]
},
"dreamer": {
"enabled": true,
"model": "anthropic/claude-sonnet-4-6"
},
"sidekick": {
"model": "anthropic/claude-haiku-4-5"
},
"experimental": {
"user_memories": { "enabled": false },
"pin_key_files": { "enabled": false }
},
"compaction_markers": false
}No explicit embedding block, so the default (provider: "local", model Xenova/all-MiniLM-L6-v2) is used.
Reproduction
- macOS 26.4.1 arm64, opencode 1.4.7, magic-context 0.9.1 (default local embedding config).
- Cached model already present at
~/.local/share/opencode/storage/plugin/magic-context/models/Xenova/all-MiniLM-L6-v2/onnx/model.onnx(90 MB,md5 = 84f837de2a0f667784facf2ba0f36b22). - Start two opencode sessions in separate terminals, in different project directories:
opencode -s ses_267e0c216ffeI6nQIAWBnt6G20opencode -s ses_26616a332ffenMsmj6S59ueIH1
- Work in both simultaneously (both sessions presumably trigger embedding/
ctx_search/dreamer init near the same time). - Within ~5 minutes, both processes die silently, no TUI error, parent shell prints nothing.
Three crash reports were generated in 17 minutes (10:56, 11:12:07, 11:12:12), all with the same native-frame signature.
Crash signatures (from ~/Library/Logs/DiagnosticReports/opencode-*.ips)
Crash 1 — opencode-2026-04-17-105636.ips
exception : EXC_BAD_ACCESS (SIGBUS)
subtype : KERN_PROTECTION_FAILURE at 0x00000004138ed418
termination: Bus error: 10
faultingThread: "Worker"
frames (top):
OrtApis::ReleaseIoBinding(OrtIoBinding*) + 24
InferenceSessionWrap::LoadModel(Napi::CallbackInfo const&) + 3220
Napi::InstanceWrap<InferenceSessionWrap>::InstanceMethodCallbackWrapper::lambda()
Napi::InstanceWrap<InferenceSessionWrap>::InstanceMethodCallbackWrapper
Crash 2 — opencode-2026-04-17-111207.ips
exception : EXC_BREAKPOINT (SIGTRAP)
termination: Trace/BPT trap: 5
faultingThread: "Worker"
frames (top):
(native, unsymbolicated + _sigtramp)
InferenceSessionWrap::LoadModel(Napi::CallbackInfo const&) + 3184
Napi::InstanceWrap<InferenceSessionWrap>::InstanceMethodCallbackWrapper::lambda()
Napi::InstanceWrap<InferenceSessionWrap>::InstanceMethodCallbackWrapper
Crash 3 — opencode-2026-04-17-111212.ips
exception : EXC_BREAKPOINT (SIGTRAP)
termination: Trace/BPT trap: 5
faultingThread: "Worker"
frames (top):
(native, unsymbolicated + _sigtramp)
OrtApis::ReleaseIoBinding(OrtIoBinding*) + 36 ← double frame!
OrtApis::ReleaseIoBinding(OrtIoBinding*) + 36 ← double-free signature
InferenceSessionWrap::LoadModel(Napi::CallbackInfo const&) + 3220
Napi::InstanceWrap<InferenceSessionWrap>::InstanceMethodCallbackWrapper::lambda()
Loaded native modules at crash time (from usedImages):
/…/onnxruntime_binding.node
/…/libonnxruntime.1.14.0.dylib
Root-cause hypothesis
All three crashes share:
- The same faulting thread name (
"Worker") — likely a transformers.js / onnxruntime-node worker pool thread. - The same top-of-stack function:
OrtApis::ReleaseIoBindinginsideInferenceSessionWrap::LoadModel. - Crash 3 shows the
ReleaseIoBindingframe twice → double-free; Crash 1 showsKERN_PROTECTION_FAILUREon a write → use-after-free.
The most plausible cause: when two opencode processes share the same on-disk ONNX model cache and both initialize InferenceSession at roughly the same wall-clock time, ONNX Runtime 1.14.0's session-initialization path releases/cleans up an IoBinding that the other process (or its own abort path) also releases — double-free → ORT_ENFORCE → brk 1 → SIGTRAP. The 1.14.0 native lib is quite old (Feb 2023) relative to macOS 26.4.1.
Suggested fixes (in order of effort)
- Lazy + singleton-initialized embedding session — ensure only one
InferenceSessionper process, behind an async-locked init. If there's already a lock, it may not be covering the fullLoadModel→ ready path. - Per-process model cache path (or file-lock the first-time extraction) — avoid two processes mmap-ing / opening the same
.onnxfile during a warm-start window. - Bump
@huggingface/transformers→ newer versions pullonnxruntime-node ≥ 1.18which carries native lib ≥ 1.18 with many post-1.14 stability fixes on Apple Silicon + newer macOS. - Graceful fallback — wrap
await pipeline(...)/InferenceSession.createin try/catch; on native crash signal or init error, auto-disable embeddings for this process instead of letting it SIGTRAP-kill the entire opencode TUI. (Currently there's zero user-visible error — the whole TUI just vanishes.) - Document the workaround —
embedding: { provider: "off" }inmagic-context.jsoncprevents the crash (ctx_search still works via FTS5 fallback). Worth noting in README until the root fix lands.
Workaround applied locally
Setting embedding.provider: "off" in ~/.config/opencode/magic-context.jsonc bypasses the crash entirely. FTS5 full-text fallback keeps ctx_search functional; only semantic ranking is lost.
Additional context
Happy to attach the full .ips files, run with any DEBUG=* env var, or test a patched build. Let me know if you want the full thread dumps — I can upload them as a gist.
Activity
ualtinok commentedon Apr 17, 2026
Fixed in v0.10.1. Thank you for the excellent repro and root-cause hypothesis — your report pointed directly at the native runtime race, and all three crash instances matched the same
ReleaseIoBindingdouble-free pattern inlibonnxruntime.1.14.0.dylib.To upgrade, run
bunx --bun @cortexkit/opencode-magic-context@latest doctor --force(the--forceclears the cached plugin install; OpenCode will fetch 0.10.1 on next start).Please reopen if you still see the crash after the upgrade, the concurrency-lock path has comprehensive fallbacks and diagnostic logs, so we can trace any residual failure from
magic-context.log(path visible indoctor).feat(plugin): cache stability v12 — deferred history refresh
fix(audit): low-severity hardening batch (#17/#19/#20/#21/#22/#23)
fix: address high-priority audit findings (cortexkit#13, cortexkit#20-…
fix(embedding): bump @huggingface/transformers to 4.1.0 and add cross…
feat(plugin): cache stability v12 — deferred history refresh
fix(audit): low-severity hardening batch (cortexkit#17/#19/cortexkit#20/
fix: address high-priority audit findings (cortexkit#13, cortexkit#20-…
fix(embedding): bump @huggingface/transformers to 4.1.0 and add cross…
lock wave: subc-core 0.17.19, subc-control 0.11.2 (+ transitive subc-…