AttributeError: 'NoneType' object has no attribute 'x'

Python · updated 2026-11-02

Raised when code reads an attribute or calls a method on None. The attribute named in the message is the one you tried to use, not the cause: the real question is which earlier expression produced None. In production it usually means an input that didn't match, a row that wasn't found, or a function that fell off the end without returning.

Traceback (most recent call last):
  File "/srv/app/jobs/import_orders.py", line 54, in parse_line
    order_id = re.match(r"ORD-(\d+)", line).group(1)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'group'

Quick fix

Split the chained expression so you can see which call returned None, then decide what None means there. re.match and re.search return None when nothing matches, dict.get returns None for a missing key, ORM lookups like .first() return None when no row matches, and a function without a return statement returns None. Handle that case explicitly instead of chaining straight into an attribute.

  1. Note the attribute in the message (here .group) and look at the expression just before it.
  2. Assign that expression to a variable and log it for the failing input.
  3. Identify which call can return None: a regex match, dict.get, a database lookup, or a function missing a return.
  4. Handle None where it is produced: skip, use a default, or raise a clear error that names the input.
  5. If None should never happen, find out why the input differs (new data format, missing row, failed earlier step).
python
m = re.match(r"ORD-(\d+)", line)
if m is None:
    log.warning("skipping line without an order id: %r", line[:80])
    return None
order_id = m.group(1)

user = session.query(User).filter_by(email=email).first()
if user is None:
    raise LookupError(f"no user with email {email!r}")

Why it happens

A regex that did not match

re.match, re.search and re.fullmatch return None when the pattern does not match, so .group() on the result fails for the first input in an unexpected format.

A lookup that found nothing

dict.get(key), ORM .first() or .one_or_none(), and many client libraries return None for "not found" instead of raising.

A function that does not return on every path

A function with no return statement, or an if branch that ends without return, returns None. The caller then fails on the next attribute it reads.

In-place methods used as if they returned the object

list.sort(), list.append() and dict.update() change the object and return None, so x = items.sort() makes x None.

An optional field that is null in the data

JSON null becomes None. A field that is present but null passes a key check and still fails on attribute access.

Other fixes

  • Type-check with mypy or pyright: Optional return types flag attribute access without a None check.
  • Validate external data at the boundary with a schema so null and missing fields fail with a clear message.
  • Prefer lookups that raise (like .one() in SQLAlchemy) where a missing row is a bug, not a normal case.

Same error, other wording

  • AttributeError: 'NoneType' object has no attribute 'get'
  • AttributeError: 'NoneType' object has no attribute 'split'
  • AttributeError: 'NoneType' object has no attribute 'id'

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the AttributeError: 'NoneType' exceptions in production, show the traceback and the input behind the latest one, work out which call returned None, and handle that case where the value is produced.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Python: Built-in exceptions (AttributeError), Python: re.match returns None when there is no match