Skip to content

fix(activation): repair reranker WASM load under Bun source/dev runs - #86

Merged
MAnders333 merged 1 commit into
MAnders333:mainfrom
dnnspaul:fix/rerank-wasm-import-bun
Aug 5, 2026
Merged

fix(activation): repair reranker WASM load under Bun source/dev runs#86
MAnders333 merged 1 commit into
MAnders333:mainfrom
dnnspaul:fix/rerank-wasm-import-bun

Conversation

@dnnspaul

@dnnspaul dnnspaul commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Problem

On every source/dev startup (bun run src/index.ts), the reranker fails to load:

[WARN] [rerank] Model load failed — reranking disabled for this process (dense-only ordering).
Reason: no available backend found. ERR: [wasm] TypeError: c is not a function.
(In 'c(m)', 'c' is ".../ort-wasm-simd-threaded.asyncify.mjs")

Reranking silently falls back to dense-only ordering, so precision degrades with no visible cause. The previous fix (ce4552c) made the reranker work in bun build --compile binaries but introduced this regression for non-binary installs.

Root cause

src/activation/rerank.ts imports the ORT WASM runtime MJS via Bun's with { type: "file" } import attribute, which yields the file path string:

import wasmRuntimeMjs from "../../node_modules/.../ort-wasm-simd-threaded.asyncify.mjs" with { type: "file" };

This path is then handed to ORT:

wasmEnv.wasmPaths = { mjs: wasmRuntimeMjs, wasm: wasmRuntimeBin };

onnxruntime-web's WASM loader resolves wasmPaths.mjs by doing await import(mjsPath).default internally. But Bun's module cache for that path already holds the path string (from the type: "file" attribute), so the dynamic import() returns { default: "<path string>" } instead of the ortWasmThreaded factory function — hence c is not a function (where c is the cached path string).

In bun build --compile single-file binaries the /$bunfs/ virtual path imports correctly, so the bug only manifests in source/dev runs (every non-binary install).

Fix

Append a cache-busting ?import query suffix to real filesystem paths so Bun treats the dynamic import() as a fresh ESM load returning the actual ortWasmThreaded factory. /$bunfs/ virtual paths (compiled binaries) already work and are left untouched:

const mjsPath = wasmRuntimeMjs.includes("/$bunfs/")
    ? wasmRuntimeMjs
    : `${wasmRuntimeMjs}?import`;
wasmEnv.wasmPaths = { mjs: mjsPath, wasm: wasmRuntimeBin };

Verification

Before:

[WARN] [rerank] Model load failed — reranking disabled for this process (dense-only ordering).
Reason: no available backend found. ERR: [wasm] TypeError: c is not a function.

After:

[INFO] [rerank] Loading cross-encoder model "Xenova/ms-marco-MiniLM-L-6-v2" ...
[INFO] [rerank] Model loaded in 0.3s — reranking active.

typecheck clean; lint unchanged (only pre-existing warnings on unrelated lines). Fail-open behavior is preserved — any load failure still falls back to dense-only ordering.

The reranker set ort.env.wasm.wasmPaths.mjs to the path string returned by
Bun's `with { type: "file" }` import attribute. onnxruntime-web's WASM
loader then does `await import(mjsPath).default` internally, but Bun's
module cache for that path already holds the path string (from the
type: "file" attribute), so the dynamic import returns { default: "<path>" }
instead of the ortWasmThreaded factory — producing:

  TypeError: c is not a function. (In 'c(m)', 'c' is
  ".../ort-wasm-simd-threaded.asyncify.mjs")

In `bun build --compile` single-file binaries the // virtual path
imports correctly, so the bug only affected source/dev runs (every
non-binary install).

Append a cache-busting `?import` query suffix to real filesystem paths so
Bun treats the dynamic import() as a fresh ESM load returning the actual
factory; leave // paths untouched. Verified: model loads in 0.3s,
reranking active.
@MAnders333
MAnders333 merged commit 9a906a2 into MAnders333:main Aug 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants