ENOENT: no such file or directory means the operating system couldn't find a file or directory at the exact path your program requested. This is a Node.js-specific error code that surfaces when filesystem operations fail because the target path doesn't exist.
What "ENOENT: no such file or directory" Means
ENOENT stands for "Error NO ENTry" — the POSIX standard error code for a missing file or directory. In Node.js, this error is thrown by the fs module (and related tools like fs.promises, readFileSync, and writeFileSync) when a path doesn't resolve to an existing file or directory. It's a hard failure: the system isn't telling you the file is locked or permission-denied — it's telling you the path is dead.
Why It Happens
The most common causes are straightforward: you're referencing a file that doesn't exist yet, you've made a typo in the path, or the working directory isn't what you think it is. In Node.js, relative paths are resolved against process.cwd() — the directory where you launched the script, not the directory where the script file lives. That mismatch alone causes a huge percentage of ENOENT errors in real projects. Another frequent trigger: your code tries to read a file before an async operation has created it, or you're passing a directory to a function that expects a file (or vice versa).
Example Code That Triggers It
Here's a minimal, runnable Node.js script that will throw ENOENT every time:
// trigger-enoent.js
import { readFileSync } from 'fs';
// This path doesn't exist relative to wherever you run this script
const data = readFileSync('./config/settings.json', 'utf8');
console.log(data);
Run it with node trigger-enoent.js from a directory that has no config/settings.json file. You'll get:
Error: ENOENT: no such file or directory, open './config/settings.json'
The error message includes the exact path Node.js tried to open, which is your first debugging clue.
How to Fix It
The fix is to ensure the path exists before you read it, or handle the error gracefully. Here's the corrected version:
// fixed-enoent.js
import { readFileSync, existsSync } from 'fs';
import path from 'path';
const filePath = path.join(process.cwd(), 'config', 'settings.json');
if (!existsSync(filePath)) {
console.error(`File not found at: ${filePath}`);
process.exit(1);
}
const data = readFileSync(filePath, 'utf8');
console.log(data);
The fix works because path.join() builds an absolute path from process.cwd(), eliminating ambiguity about where the file lives. The existsSync() check gives you a clean error message instead of a raw stack trace. For production code, wrap filesystem calls in try/catch or use fs.promises with .catch().
Common Mistakes That Cause This
The biggest mistake is using relative paths without understanding process.cwd(). If you run node src/index.js from your project root, ./config/settings.json resolves against the root — but if you run it from inside src/, it resolves against src/. Always use path.join(__dirname, ...) when you mean "relative to this file."
The second mistake: assuming a file exists because you created it in a different function earlier in the same script. Async code often races ahead of file creation. If you writeFileSync() then immediately readFileSync() in a loop, you'll sometimes hit ENOENT on the first iteration — the OS hasn't flushed the file yet.
When Should You Worry About This?
You should worry when ENOENT appears in production but not locally. That's a strong signal your deployment environment has different directory structure, missing environment variables that point to file locations, or the process is running under a different user with restricted access to certain directories. If the path is absolute and exists on your machine but fails on the server, check your deployment's working directory and file permissions first. ENOENT in a build tool (like Next.js or TypeScript) usually means a referenced asset or config file wasn't committed to version control.
Next time you see this error, check process.cwd() first — print it to the console and compare it to the path in the error message. That single step resolves most ENOENT mysteries in under a minute.