You run your script. Python stops and prints this:
FileNotFoundError: [Errno 2] No such file or directory: 'data.txt'
But the file is sitting right there in your folder. So what's going on? Below are the six causes behind this error in real programs. Each one has the exact message it gives and a fix. I ran every example on Python 3.11, 3.12 and 3.14 on Windows. All three print the same message.
What the Error Means
Your code called open(), and the operating system said it has no file at that path. Look at the end of the message. It shows the path exactly as Python got it, and that's your best clue. Either the name is wrong, or Python is searching a different folder than you think. A path like data.txt with no folder in front is a relative path. Python starts from the current working directory, not from the folder where your script lives. That one detail causes most of these errors.
How to Find the Cause Fast
Put three lines right before the open() that fails. They show where Python is looking, the full path it built, and whether that path exists:
from pathlib import Path
import os
print(os.getcwd()) # the folder Python searches from
print(Path("data.txt").resolve()) # the full path it is trying to open
print(Path("data.txt").exists()) # False means the problem is the path, not your code
Is the printed folder not the one holding your file? That's cause 1. Is the folder right? Then compare the file name letter by letter with a listing of the folder. That points to causes 2 and 3.
The Six Causes
1. You Ran Python From a Different Folder
# Run this from the folder ABOVE this one: python wrong-working-directory/bug.py
with open("data.txt") as f: # relative to where you RUN python, not where the script is
print(f.read())
Here data.txt is next to the script. But you started the script from the folder above, for example with python wrong-working-directory/bug.py. Some editors do the same when you click Run, because they use the project root. Python then looks in the wrong place. The fix is to build the path from the script's own location. That doesn't care where you run it from:
from pathlib import Path
here = Path(__file__).parent # the folder this script lives in
with open(here / "data.txt") as f:
print(f.read())
2. A Typo in the File Name
with open("scores.txt") as f: # the file is really called score.txt
print(f.read())
scores.txt and score.txt are two different files. One missing letter is enough. So is a capital letter in the wrong place (names are case sensitive on Linux and macOS), or a space where an underscore should be. Check that the path exists before you open it. If it doesn't, print what's in the folder so the mistake jumps out:
from pathlib import Path
name = "scores.txt"
if not Path(name).exists():
print(name, "not found. Files here:", sorted(p.name for p in Path(".").iterdir() if p.suffix == ".txt"))
else:
print(Path(name).read_text())
3. Windows Hid the Real Extension
with open("notes.txt") as f: # Windows hides known extensions: the real name is notes.txt.txt
print(f.read())
Windows hides the extension of known file types by default. Say you save a file as notes.txt in Notepad. The real name can end up as notes.txt.txt, while Explorer shows notes or notes.txt. You can switch on File name extensions in the Explorer View menu. Or you can list the folder from Python, like in the fix below:
from pathlib import Path
for p in sorted(Path(".").glob("notes*")): # list what is really there, extension included
print("found:", p.name)
with open("notes.txt.txt") as f: # use the real name (or rename the file)
print(f.read())
4. Writing to a Folder That Does Not Exist
with open("output/report.txt", "w") as f: # the folder "output" does not exist yet
f.write("done")
People get caught by this one. You're creating the file, so it feels like nothing needs to exist yet. But mode "w" makes the file and never the folders above it. Make the folder first. exist_ok=True keeps it from failing when the folder is already there. parents=True creates several levels at once:
from pathlib import Path
out = Path("output")
out.mkdir(exist_ok=True) # create the folder first
(out / "report.txt").write_text("done")
print("wrote", out / "report.txt")
5. A ~ in the Path
with open("~/notes_demo.txt", "w") as f: # open() does not expand "~" to your home folder
f.write("hi")
In a terminal, ~ means your home folder. That's the shell doing the work, not the terminal itself. Python doesn't do it. So open("~/notes.txt") hunts for a folder literally named ~ inside the current directory. Expand it yourself:
from pathlib import Path
target = Path("~/notes_demo.txt").expanduser() # turn "~" into your real home folder
target.write_text("hi")
print("wrote", target)
target.unlink() # clean up the demo file
6. Reading a File That Was Never Created
with open("log.txt", "r") as f: # "r" never creates a file
print(f.read())
Mode "r" is the default, and it only reads. Say your program creates a log or save file on its first run. Then the very first read fails, because nothing exists yet. Create the file if it's missing. Or open it with "a" (append), which creates it when needed:
from pathlib import Path
log = Path("log.txt")
if not log.exists():
log.write_text("") # create it first (or open with "a")
with open(log, "a+") as f:
f.seek(0)
print(repr(f.read()))
Related: OSError: [Errno 22] Invalid argument
Backslashes in a normal string are escape characters, and that bites on Windows. The path "notes\new_todo.txt" holds a newline, not the letters \n. You won't get FileNotFoundError here. I tested it, and Windows answers OSError: [Errno 22] Invalid argument. The cure is similar to the rest. Use a raw string (r"C:\temp\test.txt"), use forward slashes, or build the path with Path.
Habits That Prevent It
Use pathlib. Path(__file__).parent / "data" / "input.csv" gives you the right path on every system. It doesn't depend on the working directory. Check before you open. Path.exists() and Path.is_file() let you print a clear message instead of a traceback. Catch the error where a missing file is normal, like a settings file on the first run. Handle only that case:
from pathlib import Path
try:
text = Path("settings.json").read_text()
except FileNotFoundError:
text = "{}" # first run: start with defaults
Quick Reference
| Message or situation | Fix |
|---|---|
| File is beside the script but not found | Path(__file__).parent / "name" |
| Name looks right but fails | Compare with sorted(Path(".").iterdir()); check case and spaces |
| File was saved from Notepad on Windows | Show file name extensions; look for .txt.txt
|
Opening with "w" in a new folder |
Path(...).mkdir(parents=True, exist_ok=True) first |
Path starts with ~
|
Path(...).expanduser() |
| Reading a file the program creates later | Create it first, or open with "a"
|
The Rule, Stated Once
FileNotFoundError: [Errno 2] means the path Python built doesn't exist. So print the working directory and the resolved path. Compare them with where the file really is. Then stop relying on relative names, and build paths from the script's location with pathlib.
Want more Python errors with a clear cause? Try KeyError in Python, ValueError: invalid literal for int(), IndexError: List Index Out of Range and ModuleNotFoundError After pip install. New to Python? Start with Python for Beginners.
Download the code: the broken and fixed versions of all six causes are on GitHub in Python-projects/Troubleshooting/filenotfounderror. Run any file with python bug.py from inside its folder. The exception is wrong-working-directory, which you run from the folder above it.
Top comments (0)