Short description
globalThis[Symbol.for("onnxruntime")] injection breaks @huggingface/transformers device initialization in Electron
What happened?
This issue was written by an LLM at my direction. I verified its findings and this full text myself.
Environment:
@cortexkit/opencode-magic-context v0.29.1
@huggingface/transformers v4.2.0
onnxruntime-web v1.26.0-dev.20260416
- OpenCode Desktop v1.17.11
I'm using OpenCode Desktop and I encountered this issue. When running /ctx-embed start I get:
[magic-context] could not resolve local onnxruntime-web/dist, falling back to default WASM paths: "Package subpath './package.json' is not defined by \"exports\" in C:\\Users\\[username]\\.cache\\opencode\\packages\\@cortexkit\\opencode-magic-context@latest\\node_modules\\onnxruntime-web\\package.json"
18:52:13
general
[magic-context] Electron detected — using onnxruntime-web (WASM) for embeddings (bypasses onnxruntime-node native load)
18:52:13
general
[magic-context] embedding model failed to load: Unsupported device: "cpu". Should be one of: .
Why it breaks:
The injectWasmOrtForElectron() function at dist/index.js:166730 does two things:
- Imports
onnxruntime-web and stores it as globalThis[Symbol.for("onnxruntime")] (line 166749)
- Later,
@huggingface/transformers is imported
The problem is in @huggingface/transformers's initialization (transformers.node.mjs:11550-11579). It has three code paths:
var ORT_SYMBOL = Symbol.for("onnxruntime");
if (ORT_SYMBOL in globalThis) {
ONNX = globalThis[ORT_SYMBOL];
// supportedDevices stays [] -- NEITHER branch below runs
} else if (apis.IS_NODE_ENV) {
ONNX = ONNX_NODE; // real onnxruntime-node import
supportedDevices.push("dml"); // Windows
supportedDevices.push("webgpu");
supportedDevices.push("cpu");
defaultDevices = ["cpu"]; // <-- this is what should happen
} else {
// browser/WASM path -- also skipped
}
Because magic-context pre-populates globalThis[Symbol.for("onnxruntime")] before the import, transformers takes the first branch -- the ORT backend is set but supportedDevices stays [] and defaultDevices stays undefined.
Meanwhile, DEFAULT_DEVICE is "cpu" (line 13557, because Electron satisfies IS_NODE_ENV). When the pipeline is created at line 166890 without an explicit device option, transformers selects "cpu", calls deviceToExecutionProviders("cpu"), it checks supportedDevices.includes("cpu") -- [] doesn't include "cpu" -- and throws.
The first error (WASM path resolution) is a secondary symptom: requireFn.resolve("onnxruntime-web/package.json") fails because onnxruntime-web has an exports field that doesn't expose ./package.json. It's caught and falls back, but the device error was already inevitable regardless.
The fix:
For now I just removed one line in dist/index.js:
- globalThis[Symbol.for("onnxruntime")] = ortWeb;
Without the globalThis symbol, transformers takes the normal Node.js path, imports onnxruntime-node (its own dependency), populates supportedDevices with ["dml", "webgpu", "cpu"], and embeddings work correctly.
Diagnostics
Plugin version
0.29.1
OpenCode version
OpenCode Desktop v1.17.11
Platform
Windows x64
Client
OpenCode Desktop
Log output (optional)
Short description
globalThis[Symbol.for("onnxruntime")] injection breaks @huggingface/transformers device initialization in Electron
What happened?
This issue was written by an LLM at my direction. I verified its findings and this full text myself.
Environment:
@cortexkit/opencode-magic-contextv0.29.1@huggingface/transformersv4.2.0onnxruntime-webv1.26.0-dev.20260416I'm using OpenCode Desktop and I encountered this issue. When running /ctx-embed start I get:
Why it breaks:
The
injectWasmOrtForElectron()function atdist/index.js:166730does two things:onnxruntime-weband stores it asglobalThis[Symbol.for("onnxruntime")](line 166749)@huggingface/transformersis importedThe problem is in
@huggingface/transformers's initialization (transformers.node.mjs:11550-11579). It has three code paths:Because magic-context pre-populates
globalThis[Symbol.for("onnxruntime")]before the import, transformers takes the first branch -- the ORT backend is set butsupportedDevicesstays[]anddefaultDevicesstaysundefined.Meanwhile,
DEFAULT_DEVICEis"cpu"(line 13557, because Electron satisfiesIS_NODE_ENV). When the pipeline is created at line 166890 without an explicitdeviceoption, transformers selects"cpu", callsdeviceToExecutionProviders("cpu"), it checkssupportedDevices.includes("cpu")--[]doesn't include"cpu"-- and throws.The first error (WASM path resolution) is a secondary symptom:
requireFn.resolve("onnxruntime-web/package.json")fails becauseonnxruntime-webhas anexportsfield that doesn't expose./package.json. It's caught and falls back, but the device error was already inevitable regardless.The fix:
For now I just removed one line in
dist/index.js:- globalThis[Symbol.for("onnxruntime")] = ortWeb;Without the globalThis symbol, transformers takes the normal Node.js path, imports
onnxruntime-node(its own dependency), populatessupportedDeviceswith["dml", "webgpu", "cpu"], and embeddings work correctly.Diagnostics
Plugin version
0.29.1
OpenCode version
OpenCode Desktop v1.17.11
Platform
Windows x64
Client
OpenCode Desktop
Log output (optional)