Version: Deno 2.9.0
deno 2.9.0 (stable, release, x86_64-unknown-linux-gnu)
v8 14.9.207.2-rusty
typescript 6.0.3
Linux. Worked on an earlier 2.x — looks like a recent regression, not bisected.
Bug
When the entry module given to deno run is a symlink, Deno uses the symlink's path as the main-module URL and resolves the module's relative imports from the symlink's directory — instead of realpath-ing the entry first.
This breaks node_modules/.bin/<tool> shims (symlinks into a package's bin/), whose scripts import siblings like ../src/…. Node and Bun resolve the symlink first; Deno 2.9.0 resolves one level wrong and fails with Module not found.
Repro
mkdir -p repro/pkg/bin repro/pkg/lib repro/.bin && cd repro
printf '%s\n' '#!/usr/bin/env -S deno run --allow-all' "import {x} from '../lib/x.js';" 'console.log(x);' > pkg/bin/cli.js
echo "export const x = 'ok';" > pkg/lib/x.js
ln -s ../pkg/bin/cli.js .bin/cli # as npm creates under node_modules/.bin
deno run --allow-all .bin/cli # symlink -> error
deno run --allow-all pkg/bin/cli.js # real path -> ok
Actual
$ deno run --allow-all .bin/cli
error: Module not found "file:///…/repro/lib/x.js".
at file:///…/repro/.bin/cli:2:17
The main module is …/.bin/cli (the symlink), so ../lib/x.js resolves to repro/lib/x.js (missing) instead of repro/pkg/lib/x.js (the target's sibling). Run via the real path it prints ok.
Expected
deno run <symlink> realpaths the entry before resolving relative imports — matching Node and Bun — so both invocations print ok.
Version: Deno 2.9.0
Linux. Worked on an earlier 2.x — looks like a recent regression, not bisected.
Bug
When the entry module given to
deno runis a symlink, Deno uses the symlink's path as the main-module URL and resolves the module's relativeimports from the symlink's directory — instead of realpath-ing the entry first.This breaks
node_modules/.bin/<tool>shims (symlinks into a package'sbin/), whose scripts import siblings like../src/…. Node and Bun resolve the symlink first; Deno 2.9.0 resolves one level wrong and fails withModule not found.Repro
Actual
The main module is
…/.bin/cli(the symlink), so../lib/x.jsresolves torepro/lib/x.js(missing) instead ofrepro/pkg/lib/x.js(the target's sibling). Run via the real path it printsok.Expected
deno run <symlink>realpaths the entry before resolving relative imports — matching Node and Bun — so both invocations printok.