FileNotFoundError
[Errno 2] No such file or directory — the path, resolved against the current working directory, does not exist. Usually the file is there, but the cwd is not where you think.
Demo
from pathlib import Path for i in (1, 2, 3): Path(f'report_{i}.txt').write_text(f'report {i}') n = 2 open(f'report_{n}.txt').read()
The message ends with repr() of the path you passed — relative, exactly as typed, not the absolute path Python looked at. That is why the error rarely tells you the real problem: the name is right, but it was resolved against a different working directory. e.filename gives the same path unquoted.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| errno | int | no | errno.ENOENT when raised by the OS. With a single argument, errno stays None and the argument is the message. |
| strerror | str | no | The OS message — 'No such file or directory' from open(). |
| filename | str | bytes | None | no | The path exactly as you passed it — relative paths are not made absolute. |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| errno | int | None | errno.ENOENT (2 on Linux, macOS and Windows) when raised by the OS. |
| strerror | str | None | 'No such file or directory' from open(); Windows os.* calls give 'The system cannot find the file specified'. |
| filename | str | bytes | None | The path you passed, unchanged. Resolve it yourself with os.path.abspath(e.filename) to see where Python looked. |
| filename2 | str | None | Second path for two-path calls like os.rename(src, dst). |
Common patterns
from pathlib import Path HERE = Path(__file__).resolve().parent config = (HERE / 'config.ini').read_text()
try: with open('settings.json') as f: settings = json.load(f) except FileNotFoundError: settings = {}
import os try: f = open(path) except FileNotFoundError as e: raise SystemExit(f'{os.path.abspath(e.filename)} not found (cwd: {os.getcwd()})')
from pathlib import Path Path('cache.db').unlink(missing_ok=True)
Examples
Pitfalls
open('logs/app.log', 'w')
from pathlib import Path Path('logs').mkdir(parents=True, exist_ok=True) open('logs/app.log', 'w').write('started')
from pathlib import Path Path('app').mkdir() Path('app/config.ini').write_text('debug=1') open('config.ini').read()
from pathlib import Path Path('app').mkdir() Path('app/config.ini').write_text('debug=1') base = Path('app') (base / 'config.ini').read_text()
path = 'C:\new\table.csv' ('\n' in path, '\t' in path)
path = r'C:\new\table.csv' ('\n' in path, '\t' in path)
When to use
- Optional files: catch it and fall back to defaults
- Raising it from your own loader when a required path is missing
- Distinguishing "not there" from "not allowed" (PermissionError)
- Checking existence only → Path.exists() / os.path.exists()
- Deleting a maybe-missing file → Path.unlink(missing_ok=True)
- Creating folders → Path.mkdir(parents=True, exist_ok=True) before writing
Notes
FAQ
A relative path is resolved against the current working directory, which is where the program was started from — not the folder of the script. Running python src/app.py from the project root makes open("data.csv") look in the project root. Print os.getcwd() and os.path.abspath(path) to see where Python looked, and build paths from Path(__file__).parent.