parcel-bundler/parcel · error · FSError
ELOOP
ELOOP
Error message
ELOOP: ${path} is a symlink What it means
ELOOP raised by `ExtendedMemoryFS.openSync` when `O_NOFOLLOW` is set in the flags and the target path is a symlink. Mirrors POSIX: O_NOFOLLOW forbids following symlinks at open time.
Source
Thrown at packages/dev/repl/src/parcel/ExtendedMemoryFS.js:275
if (candidate >= FD_MAX) {
this.nextFD = 1;
candidate = this.nextFD++;
}
if (!this.openFDs.has(candidate)) {
fd = candidate;
break;
}
}
if (!fd) {
throw new FSError('EMFILE', path, 'no available file descriptor');
}
return fd;
}
openSync(filePath: FilePath, flags: number, mode: number): number {
flags = parseOpenFlags(flags);
if (flags & CONSTANTS.O_NOFOLLOW && this.symlinks.has(filePath)) {
throw new FSError('ELOOP', filePath, 'is a symlink');
}
filePath = this._normalizePath(filePath);
let file = this.files.get(filePath);
if (flags & CONSTANTS.O_CREAT) {
if (file) {
if (flags & CONSTANTS.O_EXCL) {
throw new FSError('EEXIST', filePath, 'already exists');
}
} else {
file = new File(makeShared(''), mode);
this.files.set(filePath, file);
}
}
if (!file) {
throw new FSError('ENOENT', filePath, 'does not exist');
} else if (flags & CONSTANTS.O_TRUNC) {View on GitHub (pinned to 59484858a1)
Solutions
- If following the link is intended, drop the `O_NOFOLLOW` flag.
- If the path must be a regular file, reject or fix the symlink upstream before opening.
- Resolve the real path first with `realpathSync` if you want the link target.
Example fix
// before fs.openSync(symlinkPath, O_RDONLY | O_NOFOLLOW); // ELOOP // after fs.openSync(symlinkPath, O_RDONLY); // follow allowed
Defensive patterns
Strategy: validation
Validate before calling
function openNoFollowSafe(fs, p, flags) {
if ((flags & O_NOFOLLOW) && fs.symlinks.has(p)) throw new Error(`${p} is a symlink`);
return fs.openSync(p, flags);
} Type guard
function isSymlink(fs, p) { return fs.symlinks.has(p); } Try / catch
try { return fs.openSync(p, O_RDONLY | O_NOFOLLOW); }
catch (e) { if (e.code === 'ELOOP') return fs.openSync(p, O_RDONLY); throw e; } Prevention
- Drop O_NOFOLLOW when following symlinks is acceptable.
- Resolve the real path with realpathSync first.
- Reject symlinks upstream when O_NOFOLLOW is intentional.
When it happens
Trigger: Opening a path with the `O_NOFOLLOW` flag when that path is recorded as a symlink in the memory FS; defensive opens against an attacker-controlled path that turned out to be a link.
Common situations: Security-hardened code that uses O_NOFOLLOW to avoid symlink races; tooling that opens files written by a process that created symlinks.
Related errors
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/8729017fe754e78f.
Report an issue: GitHub.