TypeError: 'NoneType' object is not subscriptable
This error means you used square-bracket notation (obj[key] or obj[index]) on a value that is None. The fix is to check for None before subscripting:
# BROKEN
result = get_data()
value = result["key"] # TypeError if get_data() returned None
# CORRECT
result = get_data()
if result is not None:
value = result["key"]
Last updated: March 2026
The Full Error
Traceback (most recent call last):
File "app.py", line 8, in <module>
name = user["name"]
TypeError: 'NoneType' object is not subscriptable
The object type in the message varies — you may see 'int' object is not subscriptable, 'float' object is not subscriptable, or 'function' object is not subscriptable. The fix pattern is the same for all of them.
What "Subscriptable" Means
A subscriptable object is one that supports the [] operator — technically, any object that implements the __getitem__ method. Built-in subscriptable types include:
| Type | Example |
|---|---|
list |
items[0] |
tuple |
coords[1] |
dict |
data["key"] |
str |
text[3] |
bytes |
raw[0] |
Custom classes with __getitem__ |
obj[key] |
Types that are not subscriptable: None, int, float, bool, function, and any custom class that does not implement __getitem__.
Cause 1: Function Returns None — the Most Common Case
In Python, any function that does not have an explicit return statement (or has a bare return) implicitly returns None. If you subscript the result without checking, you get this error.
Before (broken)
def find_user(user_id, users):
for user in users:
if user["id"] == user_id:
return user
# falls off the end — returns None implicitly
users = [{"id": 1, "name": "Alice"}]
user = find_user(999, users)
print(user["name"]) # TypeError: 'NoneType' object is not subscriptable
After (correct)
def find_user(user_id, users):
for user in users:
if user["id"] == user_id:
return user
return None # explicit — makes the intent clear
user = find_user(999, users)
if user is None:
print("User not found")
else:
print(user["name"])
Cause 2: Calling a Function Instead of Accessing Its Result
A function object is not subscriptable. If you accidentally reference a function without calling it, then try to subscript the result, you get this error.
Before (broken)
def get_config():
return {"debug": True, "port": 8080}
config = get_config # missing ()
print(config["port"]) # TypeError: 'function' object is not subscriptable
After (correct)
config = get_config() # call the function
print(config["port"]) # 8080
Cause 3: int or float Is Not Subscriptable
Numeric types do not support indexing. This usually happens when a variable holds a different type than expected.
count = 42
print(count[0]) # TypeError: 'int' object is not subscriptable
If you expected a list of numbers, check where count is assigned — it may have been overwritten with an integer earlier in the code.
Cause 4: Built-in Functions That Return None
Several common Python built-in methods modify in place and return None. Subscripting their return value is a frequent mistake.
| Expression | Returns |
|---|---|
mylist.sort() |
None |
mylist.append(x) |
None |
mylist.reverse() |
None |
mydict.update(d) |
None |
print(...) |
None |
Before (broken)
items = [3, 1, 2]
sorted_items = items.sort() # sort() returns None
print(sorted_items[0]) # TypeError: 'NoneType' object is not subscriptable
After (correct)
items = [3, 1, 2]
items.sort() # modifies in place
print(items[0]) # 1
# OR use the sorted() built-in which returns a new list
sorted_items = sorted(items)
print(sorted_items[0]) # 1
Common Mistakes Summary
| Mistake | Broken code | Fix |
|---|---|---|
Function returns None when item not found |
result = find(x); result["key"] |
Check if result is not None |
| Missing parentheses on function call | config = get_config; config["k"] |
config = get_config() |
| In-place method assigned to variable | s = items.sort(); s[0] |
Use sorted(items) or call .sort() separately |
| Variable overwritten with wrong type | data = len(data); data[0] |
Use a different variable name |
Type Checking with isinstance
When you receive data from external sources (APIs, files, user input) and need to be defensive:
def process(data):
if not isinstance(data, (dict, list)):
raise TypeError(f"Expected dict or list, got {type(data).__name__}")
return data[0]
Or use isinstance to branch on type:
result = fetch()
if isinstance(result, dict):
value = result["key"]
elif isinstance(result, list):
value = result[0]
else:
value = None
FAQ
Q: The error says 'NoneType' object is not subscriptable but I never assigned None anywhere.
A: A function you called returned None implicitly. Add a print(type(result)) just before the failing line to confirm. Then look at the function that produced result and check whether it always returns a subscriptable value in all code paths.
Q: I checked if result: but still get the error.
A: An empty list [] and empty dict {} are both falsy, but None is the specific problem here. Use if result is not None: for an explicit None check, or if result is not None and result: if you also want to guard against empty containers.
Q: How do I handle this in a one-liner without an if statement?
A: Use or {} to fall back to an empty dict, or or [] for lists:
result = get_data() or {}
value = result.get("key", "default")
Note that or {} also replaces empty dicts/lists (falsy values), so use it only when that is acceptable.
Related Pages
- Most Common Python Errors and How to Fix Them — overview of all Python error types
- Fix Python AttributeError — 'X' object has no attribute 'Y' (closely related — also triggered by None values)