NoneType Object Is Not Iterable | Fix It Fast

This TypeError means a variable became none and your code tried to loop, unpack, or build a list from it.

This error pops up when a variable you expect to hold a list, tuple, string, dict, set, or generator is actually None at runtime. The crash line is where Python tries to iterate. The real issue is usually earlier, where a value wasn’t created, a return was missed, or a lookup came back empty.

If you fix it once the right way, it tends to stop showing up across the whole module. This article walks you through what the message means, how to find the real source fast, and the fix patterns that stay clean as your codebase grows.

What The Error Means In Plain Terms

In Python, “iterable” just means “you can step through it.” A for loop steps through items one by one. Unpacking steps through items too, even if it’s only two items. Many helper functions step through inputs as well, like list(), set(), sum(), and zip().

None is different. It’s a single sentinel value that stands for “no value.” Its type is NoneType. It has no items inside it, so Python can’t step through it.

That’s why the traceback message points at iteration. The interpreter isn’t judging your logic. It’s saying, “I can’t loop this thing because it has nothing to loop through.”

  • Spot The Operation — Find the exact operation on the crash line: a loop, an unpack, or a function that consumes iterables.
  • Name The Variable — Identify the variable that is being iterated, not the variable you wish you had.
  • Trace The Last Assignment — Jump to where that variable was last set, then work one step earlier if needed.

Where None Sneaks In Most Often

This message is common because None is a normal value in Python. Many functions return it on purpose, and many APIs use it to signal “not found.” The bug starts when your code treats that “not found” signal as if it were a list of results.

Missing Return From A Function

If a function reaches its end without an explicit return, Python returns None. That’s fine when you’re writing a function that only performs side effects. It’s a problem when the caller expects a collection.

  • Check Every Branch — Make sure each if path returns the same kind of value, not a list in one branch and nothing in another.
  • Return An Empty Collection — If “no matches” is normal, return [] or () so a caller can loop with zero special cases.

In-Place Methods Returning None

Several in-place methods mutate an object and return None. A classic trap is list.sort(). The method sorts your list, but it returns None. If you do items = items.sort(), you just replaced your list with None.

  • Call In-Place Methods On Their Own Line — Write items.sort() without assigning the result.
  • Use The Non-Mutating Option — Use sorted(items) when you want a new list and a return value.

Dictionary Lookups That Miss

dict.get(name) returns None when a field isn’t present, unless you pass a default. If you treat that result as a list and iterate, you’ll hit the error.

  • Provide A Matching Default — Use payload.get("items", []) when you want “missing” to behave like “empty.”
  • Fail Early On Required Fields — If the field must exist, raise a clear error with context right where you read the dict.

Parser Calls That Return None

Many parsing helpers return None to mean “no match.” Regex searches, HTML parsers, and JSON access layers do this. The same happens with ORM lookups that return None when no row matches.

  • Branch Once — Check for None immediately after the call, then handle “found” and “not found” paths cleanly.
  • Pick The List-Returning API — When you truly want a collection, use the API that returns a list, even when it’s empty.

Fast Ways To Find The Real Source

The stack trace is your map. The last frame is the crash point. The earlier frames show how you got there. Your goal is to find the moment a value became None and decide if that was allowed.

Read The Traceback With A Repeatable Routine

  • Start At The Bottom — The bottom line shows the exact operation that tried to iterate.
  • Move Up To Your File — Skip library frames until you hit your own code, then stick with those lines.
  • Circle The Iterable — Identify the expression after in in a loop, or the value being unpacked.
  • Search For Assignments — Find where that name was set, especially from function calls and dict lookups.

Use A One-Line Probe Before The Crash

Add a tiny probe right before the failing line, run once, then remove it after the fix. Keep it plain so it doesn’t distract you during debugging.

  • Print Value And Type — Use print(items, type(items)) to confirm it’s None in that run.
  • Drop Into A Debugger — Use breakpoint() to inspect variables interactively in Python 3.7+.
  • Add A Tight Assertion — Use assert items is not None to fail earlier, closer to the cause.

Reproduce With The Smallest Input

When this error appears “random,” it’s often data-driven. Capture the failing input, shrink it, then fix the one entry point where raw data becomes the iterable your code expects.

  • Log The Boundary Data — Log the raw response, file chunk, or query parameters that produced the bad value.
  • Reduce The Case — Strip the input to the smallest example that still makes None flow into a loop.

Fix Patterns That Stay Clean

Once you know which value is None, you’ll make one of two moves. Either you ensure the upstream code always returns an iterable, or you treat None as a valid value and handle it at the call site. The clean choice depends on the contract you want.

Prefer Empty Collections Over None For “No Items”

When a function’s job is “give me items,” returning an empty collection is usually the smoothest contract. The caller can loop it without checks, and that makes the code shorter and safer.

  • Return [] For Lists — Use return [] on the “no results” branch.
  • Return () For Tuples — Use an empty tuple when callers unpack or compare tuples.
  • Return An Empty Iterator — Use return iter(()) when you want to return an iterator shape.

Coalesce At The Loop Site When You Can’t Change The Source

Sometimes the None comes from a third-party package, a shared utility, or a legacy interface you don’t want to touch. In that case, keep your loop safe with a clear default.

  • Use An Or Default — Write for row in (rows or []): when None should mean “no rows.”
  • Branch With is None — Use if rows is None: when you want a separate path, like raising or returning.
  • Match The Expected Type — Default to [] when you loop lists, default to {} when you loop dict names.

Keep Return Types Stable Across All Branches

Mixed return types turn small bugs into recurring ones. If a function returns a list on Monday and None on Tuesday, every caller has to track that detail. It only takes one missed check to crash.

  • Pick A Contract And Stick To It — “Always list” or “list or raise” are both clear.
  • Write A Short Docstring — One sentence beats guesswork during refactors.
  • Add Type Hints — Hints like -> list[str] push warnings into your editor before runtime.

NoneType Object Is Not Iterable In Real-World Code Paths

This section gives you concrete scenarios that trigger the error. Each one includes a fix that keeps code readable and avoids sneaky side effects. You’ll also see nonetype object is not iterable in logs written in lower case, so spotting it gets easier.

Looping Over A Function Result

A common pattern is for item in fetch_items():. If fetch_items() returns None for the empty case, the loop breaks. Most apps are happier when the function returns [] for “no items.”

  • Return A List Every Time — Build a list and return it, even if the list is empty.
  • Raise On Invalid State — If empty is not allowed, raise a clear error inside the function, not in the caller.

Unpacking A Maybe-None Value

Unpacking is also iteration. If you do a, b = get_pair() and the function returns None, Python can’t pull out two values. This tends to happen with parsing helpers that return (x, y) for a match and nothing for no match.

  • Return A Two-Item Tuple — Use return (None, None) when you want unpacking to stay valid.
  • Branch Before Unpack — Return the pair object, test it, then unpack only on the match path.

Sorting Then Iterating

The in-place sort trap often shows up during quick refactors: items = items.sort(), then for x in items:. The loop line crashes, but the mistake is the assignment. The fix is tiny.

  • Use sorted() — Write items = sorted(items) when you want assignment.
  • Sort Without Assignment — Write items.sort(), then loop items on the next line.

Iterating Over JSON Fields That Are Missing Or null

JSON adds another wrinkle: a missing field and a null value are different states. Either one can become None in Python, and a loop will crash unless you set a default. The table below maps common cases to safe loop inputs.

Incoming Value What You’ll See In Python Safe Loop Expression
Field missing payload.get("items") returns None payload.get("items", [])
items: null payload["items"] is None payload.get("items") or []
items: [] An empty list payload["items"]

Iterating Over A Database Result That Can Be Empty

Database libraries differ. Some return empty lists. Some return None from “fetch one.” If you treat a “fetch one” result as a list of rows, you’ll get this error. Fix it by choosing the API that matches your loop.

  • Use fetchall For Row Lists — Loop over a list of rows, not a single row object.
  • Handle fetchone Separately — Treat a single-row result as a single object, not a collection.

Stopping A NoneType Not Iterable Error From Returning

After you patch the crash, it’s worth adding a couple of small guardrails. They reduce the chance of the same bug reappearing during the next refactor or data shape change.

  • Write Tests For Empty Paths — Add a test where the list is empty, the field is missing, or the parser finds no match.
  • Validate At Boundaries — When raw input enters your code, validate shape once, then work with a clean internal shape.
  • Log With Context — Log which user, file, request id, or record caused a missing value so you can reproduce quickly.
  • Avoid Silent None Returns — If a function must return items, don’t let it “fall off the end.” Make every branch explicit.
  • Review In-Place Methods — Watch for methods that return None and keep them off the right side of =.

If you keep seeing nonetype object is not iterable across different files, treat it as a sign that your return contracts aren’t consistent. Pick one contract for each function, stick to it, and the error usually disappears with fewer lines changed than you’d expect.

One last check: after your fix, run the path that used to fail with empty input, missing fields, and a normal case. If all three pass, you’re done each time.