parcel-bundler/parcel · error · FSError
EMFILE
EMFILE
Error message
EMFILE: ${path} no available file descriptor What it means
EMFILE raised by `ExtendedMemoryFS._nextFD` when the in-memory FS has `FD_MAX` open file descriptors and none are free. This is a descriptor leak: opens without matching closes exhaust the table.
Source
Thrown at packages/dev/repl/src/parcel/ExtendedMemoryFS.js:267
throw new FSError('ENOENT', path.dirname(oldPath), "wasn't found");
}
_nextFD(path: FilePath): number {
let tested = 0;
let fd;
while (tested < FD_MAX) {
let candidate = this.nextFD++;
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');
}View on GitHub (pinned to 59484858a1)
Solutions
- Ensure every successful `openSync` is paired with `closeSync` in a finally block.
- Limit concurrent opens with a small pool/queue.
- If FD_MAX is genuinely too low for your workload, raise it in the FS config — but a leak is the more likely cause.
Example fix
// before
const fd = fs.openSync(p, O_RDONLY);
use(fs.readSync(fd, ...));
// after
const fd = fs.openSync(p, O_RDONLY);
try { use(fs.readSync(fd, ...)); }
finally { fs.closeSync(fd); } Defensive patterns
Strategy: try-catch
Validate before calling
function assertFDFree(fs) {
// expose openFDs size; fail fast before openSync if near FD_MAX
if (fs.openFDs.size >= FD_MAX) throw new Error('FD table full — close handles');
} Try / catch
let fd;
try { fd = fs.openSync(p, flags); /* ... */ }
finally { if (fd != null) fs.closeSync(fd); } Prevention
- Always pair openSync with closeSync in a finally block.
- Bound concurrent opens with a pool.
- Treat EMFILE as a leak signal, not a capacity ceiling.
When it happens
Trigger: Repeated `openSync` without `closeSync`, exceeding FD_MAX; a transformer/packager that opens many files concurrently and forgets to close them.
Common situations: Long-running REPL sessions that accumulate handles; bulk operations opening many assets; missing `fs.closeSync(fd)` after reads/writes.
Related errors
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/1cb9d3c978bcf96e.
Report an issue: GitHub.