TypeError: 'NoneType' object is not iterable
1 · The lesson
readWhat this error means
You tried to loop over (or unpack, or *-spread) something that turned out to be None. None is Python's "nothing" value — it has no elements, so iteration is meaningless. Almost every time you see this, a function you expected to return a list/dict/tuple actually returned None, usually because a return statement was missing or skipped.
When you see it
Traceback (most recent call last): File "main.py", line 8, in <module> for name in get_names(): TypeError: 'NoneType' object is not iterable
Why it happens
A Python function that "falls off the end" without hitting a return returns None. So does a function whose return is hidden inside an if branch that didn't run. The caller then tries to iterate over None, and Python complains.
def get_names(active=True): if active: return ["alice", "bob"] # implicit `return None` when active is False for name in get_names(active=False): # boom print(name)
Other common triggers: list-mutating methods (list.sort(), list.append(), list.reverse()) return None, not the list. Assigning their result and then iterating gives the same error.
How to fix it
Add the missing return, or return an empty collection so the caller can always iterate:
def get_names(active=True): if active: return ["alice", "bob"] return [] # never return None for a "list-returning" function
Don't assign the result of in-place methods:
nums = [3, 1, 2] nums.sort() # mutates in place — returns None # for n in nums.sort(): # wrong: iterates over None for n in nums: # right print(n) # If you want a new sorted list without mutating: for n in sorted(nums): print(n)
Guard the call site if None is genuinely a valid return value:
result = lookup(user_id) if result is not None: for row in result: ...
setup added so this can run · defines lookup, user_id
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) def lookup(*_a, **_kw): print('-> lookup() called') return _AutoMock('lookup()') user_id = _AutoMock('user_id')
When you'd actually see this in real code
- A
find_user()helper returnsNonewhen the user doesn't exist, but the caller iterates blindly. re.match(...)returnsNoneon no match — and you tried to unpack its groups.dict.get("key")returnsNonewhen the key is missing and you looped over it expecting a list.- You wrote
names = names.sort()instead ofnames.sort()ornames = sorted(names).
Related errors
- AttributeError: 'NoneType' object has no attribute 'X' — same root cause, different symptom.
- NameError: name 'X' is not defined — sometimes mistaken for this when a return is forgotten.
- TypeError: 'int' object is not subscriptable
See Also
- All Python errors — the full index, by type and by when it happens.
- Functions (tutorial)
- Control flow cheat sheet
- Lists (tutorial)