parcel-bundler/parcel · error · FSError
ENOENT
ENOENT
Error message
does not exist
What it means
Thrown by OverlayFS._deletedThrows() when the given filePath is in the `deleted` Set. OverlayFS layers a writable filesystem on top of a readable one; when a file is deleted via the overlay, it's not removed from the readable layer but instead added to the `deleted` set to mask it. Any subsequent access throws ENOENT to honor the deletion.
Source
Thrown at packages/core/fs/src/OverlayFS.js:66
serialize(): {|
$$raw: boolean,
readable: FileSystem,
writable: FileSystem,
deleted: Set<FilePath>,
|} {
return {
$$raw: false,
writable: this.writable,
readable: this.readable,
deleted: this.deleted,
};
}
_deletedThrows(filePath: FilePath): FilePath {
filePath = this._normalizePath(filePath);
if (this.deleted.has(filePath)) {
throw new FSError('ENOENT', filePath, 'does not exist');
}
return filePath;
}
_checkExists(filePath: FilePath): FilePath {
filePath = this._deletedThrows(filePath);
if (!this.existsSync(filePath)) {
throw new FSError('ENOENT', filePath, 'does not exist');
}
return filePath;
}
_isSymlink(filePath: FilePath): boolean {
filePath = this._normalizePath(filePath);
// Check the parts of the path to see if any are symlinks.
let {root, dir, base} = path.parse(filePath);
let segments = dir.slice(root.length).split(path.sep).concat(base);
while (segments.length) {View on GitHub (pinned to 59484858a1)
Solutions
- Check `overlayFS.deleted.has(filePath)` before accessing a path that may have been deleted.
- Use existsSync on the OverlayFS which accounts for the deleted set rather than checking the underlying readable layer directly.
- If you need to restore a deleted file, create a new OverlayFS instance or remove the path from the deleted set programmatically.
Example fix
// before
let content = await overlayFS.readFile(filePath); // throws if deleted
// after
if (!overlayFS.deleted.has(path.normalize(filePath))) {
let content = await overlayFS.readFile(filePath);
} Defensive patterns
Strategy: validation
Validate before calling
// Check deleted set before accessing OverlayFS paths
function isDeleted(overlayFS, filePath) {
const normalized = overlayFS._normalizePath(filePath);
return overlayFS.deleted.has(normalized);
}
// Usage:
if (!isDeleted(overlayFS, filePath)) {
await overlayFS.readFile(filePath);
} Type guard
// Guard: check if the filesystem is an OverlayFS with a deleted Set
function isOverlayFS(fs) {
return fs instanceof Object &&
fs.deleted instanceof Set &&
'writable' in fs &&
'readable' in fs;
} Try / catch
try {
await overlayFS.readFile(filePath);
} catch (e) {
if (e.code === 'ENOENT' && overlayFS.deleted.has(overlayFS._normalizePath(filePath))) {
// File was logically deleted — recreate or skip
} else {
throw e;
}
} Prevention
- Track which files your code deletes and avoid accessing them without restoring.
- Use existsSync on the OverlayFS (which respects the deleted set) rather than checking the readable layer directly.
- When implementing cache invalidation, consider recreating the OverlayFS or clearing the deleted set to avoid stale deletion state.
When it happens
Trigger: Calling any OverlayFS read/write/stat method that internally calls _deletedThrows on a path previously removed via `overlayFS.unlink()` or `overlayFS rimraf()`. The deleted Set persists for the lifetime of the OverlayFS instance.
Common situations: A Parcel build deletes a cached asset file, then a later stage (or re-run) tries to read it without clearing the deleted state. Hot-module replacement (HMR) logic deletes a file on change, then a stale reference tries to re-read it. Cache invalidation doesn't clear the deleted set, causing false ENOENT on files that still exist in the readable layer.
Related errors
- ENOENT
- ENOENT
- ${path.relative(process.cwd(), source)} is not a file.
- Unknown entry: ${entry}
- Could not find parcel config at ${path.relative(options.proj
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/b08b4499a4c4292b.
Report an issue: GitHub.