Skip to content

Commit 09564b2

Browse files
jahoomaclaude
andcommitted
Use argv[0] (not execPath) to find sibling wasm — pre-init fix on Windows
Round 6's diagnostic dump on Windows revealed why existsSync(siblingPath) was returning false even though the wasm file was right next to the binary: [smoke diag] execPath=D:\a\codebuff\codebuff\cli\bin\codebuff.exe [smoke diag] siblingExists=true (in main()) [smoke diag] globalThis wasmBinary bytes=0 (set by pre-init) Aborted(Error: ENOENT: no such file or directory, open 'B:\~BUN\root\tree-sitter.wasm') Pre-init runs at module load. main() runs later. The diag is in main(), which sees execPath as the disk path. But the ENOENT line shows what pre-init actually saw: `B:\~BUN\root\tree-sitter.wasm` — the *bunfs internal* path. So inside a bun --compile binary on Windows, `process.execPath` returns the bunfs path during early module evaluation and only switches to the disk path later. Pre-init silently bailed because that bunfs sibling doesn't exist. Switch pre-init to use process.argv[0] instead. argv[0] is the path the binary was *invoked with* — always a real disk path, not a bunfs internal one. Try execPath as a fallback for environments where argv[0] is somehow exotic. Whichever yields an existing sibling wins. Verified locally on macOS where execPath was already the disk path: build copies wasm to bin/, pre-init finds and reads it, --smoke-tree-sitter exits 0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d642f94 commit 09564b2

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

cli/src/pre-init/tree-sitter-wasm.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,29 @@
2020
// zero bundler involvement.
2121

2222
import { existsSync, readFileSync } from 'fs'
23-
import { dirname, join } from 'path'
23+
import { dirname, isAbsolute, join, resolve } from 'path'
2424

25-
// Sibling path: same directory as the running binary. Works for both
26-
// production binaries (where the downloader places tree-sitter.wasm
27-
// next to the executable) and dev runs (path won't exist, falls
28-
// through to init-node.ts's path-based resolution which finds the
29-
// node_modules copy).
30-
const siblingPath = join(dirname(process.execPath), 'tree-sitter.wasm')
25+
// Where to look for the sibling tree-sitter.wasm. We can't just use
26+
// `dirname(process.execPath)`: at pre-init time inside a bun --compile
27+
// binary on Windows, `process.execPath` returns the *bunfs* internal
28+
// path (`B:\~BUN\root\<binary>.exe`) rather than the on-disk path of
29+
// the .exe the user invoked. By the time main() runs it switches to
30+
// the disk path, but pre-init has long since bailed out.
31+
//
32+
// Try several sources in order; the first whose sibling .wasm exists
33+
// wins. argv[0] is normally the path the binary was invoked with —
34+
// always a real disk path, never bunfs. execPath is kept as a fallback
35+
// for environments where argv[0] is something exotic.
36+
const candidates = (
37+
[process.argv[0], process.execPath] as Array<string | undefined>
38+
)
39+
.filter((p): p is string => typeof p === 'string' && p.length > 0)
40+
.map((p) => (isAbsolute(p) ? p : resolve(p)))
41+
.map((p) => join(dirname(p), 'tree-sitter.wasm'))
42+
43+
const siblingPath = candidates.find((p) => existsSync(p))
3144

32-
if (existsSync(siblingPath)) {
45+
if (siblingPath) {
3346
// Tell init-node.ts (in code-map / the SDK bundle) where the wasm
3447
// is. The locateFile callback there will hand this path to
3548
// emscripten, which fs.readFile's it.

0 commit comments

Comments
 (0)