Skip to content

Commit 4b5620c

Browse files
George-iamclaude
andcommitted
fix(search): cross-platform dynamic import + Windows VC++ Redist hint
Two fixes for `axme-code config set context.mode search` on Windows: 1. **pathToFileURL on dynamic import.** `await import(absolutePath)` throws on Windows because Node treats raw `C:\...` paths as bare specifiers. Wrapping the resolved path with `pathToFileURL(...).href` produces a `file:///C:/...` URL that imports cleanly on every platform. 2. **Actionable error when onnxruntime-node native binding fails to load.** Most common Windows failure: `onnxruntime_binding.node` throws "specified module could not be found" because Microsoft Visual C++ Redistributable is missing. We now detect that signature and print a clear hint pointing to the redist installer plus the retry command, instead of returning null silently and leaving the user to chase a generic "module not loaded" message from search-install.ts. Verified on Azure Win11 native: - Before VC++ Redist install: error message correctly directs the user to https://aka.ms/vs/17/release/vc_redist.x64.exe. - After VC++ Redist install: `axme-code config set context.mode search` succeeds end-to-end (31/31 entries indexed in 5s, embeddings.json written, config.yaml updated). - claude --print session calls axme_context (renders search-mode catalog) and axme_search_kb (top hits semantically correct: D-004 + D-002 for "git push force safety" query). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent dcc62ef commit 4b5620c

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

src/storage/embeddings.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { createRequire } from "node:module";
2626
import { existsSync, statSync } from "node:fs";
2727
import { homedir } from "node:os";
2828
import { join } from "node:path";
29+
import { pathToFileURL } from "node:url";
2930
import { atomicWrite, ensureDir, readSafe } from "./engine.js";
3031

3132
export type EmbedType = "memory" | "decision";
@@ -89,15 +90,36 @@ export async function loadEmbedder(): Promise<Embedder | null> {
8990
if (!isRuntimeInstalled()) return null;
9091

9192
// Dynamic import via createRequire so we can resolve from the lazy runtime
92-
// location at runtime regardless of where the CLI bundle lives. Typed as
93-
// `any` because @huggingface/transformers is intentionally NOT a build-time
93+
// location regardless of where the CLI bundle lives. Typed as `any`
94+
// because @huggingface/transformers is intentionally NOT a build-time
9495
// dependency — it's lazy-installed on opt-in.
96+
//
97+
// pathToFileURL is mandatory on Windows: Node's dynamic import refuses
98+
// raw absolute paths like `C:\...\index.js` (treats them as bare
99+
// specifiers and looks for a package). file:// URLs work everywhere.
95100
const runtimeRequire = createRequire(join(RUNTIME_DIR, "node_modules", ".package-lock.json"));
96101
let mod: any;
97102
try {
98103
const requirePath = runtimeRequire.resolve("@huggingface/transformers");
99-
mod = await import(requirePath);
100-
} catch {
104+
mod = await import(pathToFileURL(requirePath).href);
105+
} catch (e) {
106+
// The most common Windows failure mode here is "specified module could
107+
// not be found" thrown while loading onnxruntime-node's native
108+
// .node binding because Microsoft Visual C++ Redistributable isn't
109+
// installed. Surface an actionable hint instead of returning null
110+
// silently and leaving the user to interpret the deferred error.
111+
const msg = (e as Error)?.message ?? String(e);
112+
if (process.platform === "win32" && /could not be found|onnxruntime_binding\.node/i.test(msg)) {
113+
process.stderr.write(
114+
"AXME: failed to load semantic-search runtime. The most common cause on Windows is\n" +
115+
" a missing Microsoft Visual C++ Redistributable (required by onnxruntime-node).\n" +
116+
" Install from https://aka.ms/vs/17/release/vc_redist.x64.exe and retry\n" +
117+
" `axme-code config set context.mode search` (or `axme-code reindex`).\n" +
118+
` Underlying error: ${msg}\n`,
119+
);
120+
} else {
121+
process.stderr.write(`AXME: failed to load semantic-search runtime: ${msg}\n`);
122+
}
101123
return null;
102124
}
103125

0 commit comments

Comments
 (0)