Repository navigation
bundle stage fails from any cwd other than the engine checkout: tsx resolves the @/ alias from the caller's directory #470
Description
Activity
- addedbugSomething isn't workingSomething isn't workingbuildBuild, packaging and developer setupBuild, packaging and developer setupplatformOS / toolchain portabilityOS / toolchain portability
on Sep 14, 2026 Reproduced on TypeScript too, from the callgraph-benchmark adapter (cwd = the benchmark checkout), engine d54837c, Node 24.11.1:
run-souffle.sh --language typescripton the benchmark's TS torture subject solves (116 s,out/raw/call-chain-edges.csv72 rows), then exits 1 withCannot find module '@/bundle/build'.Verified workaround, no change to the checkout:
TSX_TSCONFIG_PATH=<engine>/tsconfig.jsonin the environment.$ cd /tmp && <engine>/node_modules/.bin/tsx <engine>/src/bundle/cli.ts --print-schema Error: Cannot find module '@/bundle/build' $ cd /tmp && TSX_TSCONFIG_PATH=<engine>/tsconfig.json <engine>/node_modules/.bin/tsx <engine>/src/bundle/cli.ts --print-schema # The output bundle — schemaWith that set, the benchmark ran axiom end to end on kysely (1,907/2,452 exact, unchanged from engine 9f5e90e). Exporting it inside
run-souffle.shbefore the bundle stage is a one-line fix.Reproduced from the call-graph benchmark, which runs
run-souffle.shfrom its own work directory, on engine69a0383withnpm cidone in the engine checkout:Error: Cannot find module '@/bundle/build' Require stack: - …/axiom-code-graph/src/bundle/cli.tsThe solve itself completes (
Elapsed (solve): 36s). The bundle stage then exits non-zero, so every caller sees the whole run as failed.A workaround needing no code change, verified on the Java and TypeScript torture subjects and on maven-core:
TSX_TSCONFIG_PATH=<engine>/tsconfig.json bash <engine>/src/pipeline/run-souffle.sh …(tsx 4.23.1 honours it.) A robust fix inside the script would be to export
TSX_TSCONFIG_PATH="$PKG/tsconfig.json", or pass--tsconfig "$PKG/tsconfig.json", just before invoking"${BUNDLE[@]}".Downstream impact, for triage: this is one of the two reasons the call-graph benchmark currently reports no axiom row at all, in Java or TypeScript (AxiomCodeAI/callgraph-benchmark#81). The benchmark invokes
run-souffle.shfrom its own repository root, so the bundle stage fails withCannot find module '@/bundle/build'before the adapter runs. Reproduced at engined54837cand69a0383fromcallgraph-benchmark85533cd.TSX_TSCONFIG_PATH=<engine>/tsconfig.jsonworks around it, and with that set the scores reproduce the committed rows (details in the benchmark issue). Not re-tested after #469 moved the stage tograph/bundle/cli.ts.- added a commit that references this issue
on Sep 14, 2026 - added 3 commits that reference this issue
on Sep 19, 2026
run-souffle.shlaunches the bundle stage asnode_modules/.bin/tsx src/bundle/cli.ts.cli.tsimports its neighbours through the
@/path alias declared intsconfig.json. tsx resolves thatalias from the tsconfig it discovers relative to the process's working directory, not relative
to the script it was given. So the stage works when the caller's cwd is the engine checkout — which
is how the three regression suites invoke it — and fails from any other directory with
Soufflé has already solved by then;
raw/is complete and the run reports "solve failed" forwhat is a module-resolution fault in the last step.
Reproduce
<out>/raw/is written;<out>/graph.sqliteis not. Run the identical command withcd <engine>first and the bundle appears.
Why it matters
Every consumer other than the suites runs the executor from the analysed repository, not from
the engine checkout — a skill, a CLI wrapper, an agent's working directory. The
dist/bundle/cli.jspath (taken when tsx is absent) does not have this problem, so an installed package is fine and a
development checkout is the one that breaks, which is the reverse of what a developer expects.
Fix
Either
cd "$PKG"(with every path already absolute, which they are) before invoking the stage,or point tsx at the config explicitly (
--tsconfig "$PKG/tsconfig.json"), or drop the alias insrc/bundle/*for relative imports so resolution does not depend on a config file being found.