Handle broken symlinks gracefully during file tracing
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 1.7k
- Forks
- 185
- PR merge metrics
- No merged PRs in 30d
Description
Bug Description
When @vercel/nft traces dependencies in an environment containing broken symlinks
(symlinks whose target does not exist), the tracing process throws an unhandled
ENOENT error and aborts entirely.
Steps to Reproduce
- Create a broken symlink in the system (e.g.,
/etc/alternatives/which.sl1.gz
pointing to a non-existent target) - Run
nodeFileTrace()on an entry file whose dependency chain resolves through
that directory (e.g., via a binary that references/usr/bin/which→
/etc/alternatives/which) - The trace fails with: Error: ENOENT: no such file or directory, stat '/etc/alternatives/which.sl1.gz'
Expected Behavior
Broken symlinks should be skipped gracefully (similar to how _internalReadlink
already handles ENOENT by returning null). The trace should continue and
simply not include the broken symlink target in the output fileList.
Actual Behavior
The entire trace aborts with an unhandled ENOENT error, preventing any output
from being generated.
Environment
@vercel/nftversion: 0.29.2- Node.js: 20.x
- OS: Linux (CI container based on CentOS/Alpine with stale symlinks in
/etc/alternatives)
Analysis
In src/fs.ts, _internalStat correctly returns null for ENOENT. However,
the realpath() method in src/node-file-trace.ts recursively resolves paths
by calling readlink → resolve → realpath again. During this recursion,
when the resolved path traverses a directory that contains broken symlinks,
subsequent operations on adjacent files (like glob-based asset emission or
shared library detection) may attempt to stat those broken symlinks through
a code path that does not handle the null/ENOENT return gracefully.
Suggested Fix
Ensure that any code path that calls stat() or processes directory entries
during tracing handles broken symlinks (stat returning null) by skipping
the entry rather than propagating the error.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/fs.ts and src/node-file-trace.ts, following nodeFileTrace into realpath and the directory-entry paths that call stat. Compare those paths with _internalReadlink and _internalStat, then reproduce the broken-symlink scenario on Node.js. Done means tracing continues after ENOENT and the broken target is absent from fileList.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- devtools, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100