Article
TypeError: 'NoneType' object is not subscriptable — the debug recipe
This error means a function handed you None and you tried to index it. Learn the three functions that return None most often and the two-line guard that fixes them.
On this page0%
- The shape of the bug
- Step 1 — Find which variable is None
- Step 2 — Check the usual suspects
- Step 3 — Fix the OpenCV version properly
- Step 4 — Guard regex results
- Step 5 — Use safe defaults for dictionaries
- Sibling errors you will meet
- The habit that prevents all of it
- FAQ
- What does 'NoneType' object is not subscriptable mean?
- Why does cv2.imread return None?
- How do I check for None in Python?
- Why does my function return None when I did not write return None?
- What is the difference between not subscriptable and not iterable?
- Next reading on Sythra Articles
TypeError: 'NoneType' object is not subscriptable sounds cryptic. It says something simple:
You used square brackets on
None, andNonehas nothing inside it.
NonePython's word for "no value at all" is what a function returns when it has nothing useful to give back. None[0], None["name"], and None[1:3] are all meaningless, so Python stops.
The real bug is never on the line that crashed. It is wherever None was created. This guide shows you how to find that spot in about a minute.
The shape of the bug
import cv2
image = cv2.imread("photo.jpg") # <- the real bug lives here
print(image[0]) # <- but the crash happens here
cv2.imread returns None when it cannot read the file. It does not raise an error and it does not warn you. The program keeps going until something tries to index the result.
Step 1 — Find which variable is None
Print the value and the type right before the failing line:
print("value:", image)
print("type:", type(image))
If you see value: None and type: <class 'NoneType'>, you have found the guilty variable. Now walk upward to the line that assigned it.
Step 2 — Check the usual suspects
Four calls produce None far more often than anything else:
| Call | Returns None when | Fix |
|---|---|---|
cv2.imread(path) | File missing, wrong path, or unsupported format | Check the path exists before reading |
re.match() / re.search() | The pattern did not match | Test the result before using .group() |
dict.get(key) | The key is absent | Pass a default: d.get(k, {}) |
| A function of your own | Some branch has no return | Return a value on every path |
That last one catches almost everyone at least once:
# Broken — nothing is returned when the list is empty
def first_item(items):
if items:
return items[0]
result = first_item([])
print(result[0]) # TypeError: 'NoneType' object is not subscriptable
Python inserts an invisible return None at the end of any function that falls off the bottom. Make the empty case explicit:
# Fixed
def first_item(items):
if items:
return items[0]
return "" # a real value, every time
Step 3 — Fix the OpenCV version properly
This is the number one source of the error for anyone learning computer vision. Do not just check for None; check the path and say why it failed:
from pathlib import Path
import cv2
path = Path("photo.jpg")
if not path.exists():
raise FileNotFoundError(f"No such file: {path.resolve()}")
image = cv2.imread(str(path))
if image is None:
raise ValueError(f"OpenCV could not decode: {path.resolve()}")
print("Loaded:", image.shape)
path.resolve() prints the full absolute path, which instantly reveals the usual culprit: your script runs from a different folder than you think, so "photo.jpg" points somewhere unexpected.
The same trap exists for video:
cap = cv2.VideoCapture(0)
if not cap.isOpened():
raise RuntimeError("Camera did not open. Is another app using it?")
ok, frame = cap.read()
if not ok or frame is None:
raise RuntimeError("Camera opened but returned no frame.")
We use exactly this guard in the virtual mouse project, because a webcam that silently returns None is a miserable thing to debug.
Step 4 — Guard regex results
re.search returns None on no match, and None.group() fails the same way:
import re
match = re.search(r"(\d{4})", "no digits here")
if match is None:
print("No year found")
else:
print("Year:", match.group(1))
The walrus operator makes this tidier in modern Python:
if (match := re.search(r"(\d{4})", text)) is not None:
print("Year:", match.group(1))
Step 5 — Use safe defaults for dictionaries
Chained .get() calls are the classic source of this error in API code:
# Broken — 'address' may not exist
city = data.get("address")["city"]
# Fixed — an empty dict is still subscriptable
city = data.get("address", {}).get("city", "unknown")
The trick: give .get() a default of the same shape as the real value. A missing dict becomes {}, a missing list becomes []. The next operation then works instead of exploding.
Sibling errors you will meet
| Error | Meaning |
|---|---|
'NoneType' object is not iterable | You looped over None |
'NoneType' object has no attribute 'x' | You used a dot on None |
'NoneType' object is not callable | You called None() |
All four have the same cure: find where None was born and handle that case.
The habit that prevents all of it
Check for None immediately after the call that could produce it — not three lines later, not in the function that uses the value. Fail loudly, with the path or key in the message. Debugging a clear error takes seconds; debugging a NoneType crash forty lines downstream takes an evening.
FAQ
What does 'NoneType' object is not subscriptable mean?
It means you used square brackets on a variable holding None. Because None contains no items, indexing, slicing, and key lookup are all invalid.
Why does cv2.imread return None?
The file path is wrong relative to where the script runs, the file is missing, or the format cannot be decoded. Print Path(p).resolve() to see the absolute path OpenCV actually tried.
How do I check for None in Python?
Use if value is None:, not ==. The is operator compares identity, which is the correct and fastest check for None.
Why does my function return None when I did not write return None?
Python adds an implicit return None whenever execution reaches the end of a function without hitting a return. An if with no matching else is the most common cause.
What is the difference between not subscriptable and not iterable?
Not subscriptable means you used [] on None. Not iterable means you tried to loop over None with a for statement. Both point back to the same missing value.