}

Fix Python 'TypeError: X object is not subscriptable' (2026)

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