ErrorPython

TypeError: NoneType object is not subscriptable

Why TypeError: NoneType object is not subscriptable happens, the common ways a value quietly becomes None, and how to trace it to the real cause.

Last updated

ErrorPython
TypeError: 'NoneType' object is not subscriptable

What it means: Somewhere in your code you tried to index or slice a value (`x[0]`, `x['key']`) that turned out to be `None` instead of the list, dict, or string you expected.

Likely causes

Most probable first — with how to confirm.

  • 1.A function you called returns `None` implicitly — no `return` statement on some code path, or a bare `return` — and you're indexing its result directly; check every `return` path of that function, especially early returns.
  • 2.A dict lookup with `.get('key')` returns `None` when the key is missing, unlike `dict['key']`, which would raise `KeyError` instead — and that `None` is then indexed into.
  • 3.An API call, regex match, or database query that can legitimately return 'nothing found' (`re.match` returning `None`, an ORM `.first()` returning `None`) is used without checking for that case first.
  • 4.A variable was set to `None` as an initial placeholder, and a conditional that was supposed to overwrite it with a real value didn't run on this path.

Fixes

Safest first; destructive ones are called out.

  • →Find the exact line from the traceback and check what's `None` there — print it or drop into a debugger (`pdb`, `breakpoint()`) right before the failing line to confirm which variable is unexpectedly `None`.
  • →Add an explicit check before indexing — `if result is not None: result[0]` — and decide what should actually happen in the `None` case instead of assuming it can't occur.
  • →For a dict lookup, use `.get('key', default)` with a sensible default, or confirm with `'key' in d` before indexing, rather than assuming the key exists.
  • →Trace back to why the value became `None` in the first place — fixing the symptom at the indexing site often just moves the bug rather than removing it.

Part by part

TypeError
The operation is not supported for this type. Python is not saying the value is missing — it is saying you cannot do that to a None.
'NoneType' object
The type of None. Seeing it here means something returned None where you expected a container, which is a source problem rather than a usage one.
is not subscriptable
Square-bracket access was attempted. The related message "has no attribute" means dot access instead, and both point at the same underlying cause.

Common mistakes

  • if value is not None: value['key']

    Suppresses the crash without answering why the value was None. The code now silently does nothing in a case you have not understood, which is harder to debug than the exception was.

  • value = value or {}

    A reasonable default when None genuinely means empty, and a bug when it means "the lookup failed". It also treats 0 and the empty string as missing, which is rarely intended.

  • try: value['key'] except TypeError: pass

    Catches the symptom at its widest, so an unrelated TypeError from inside the block is swallowed too. If you must catch, catch narrowly and log what happened.

Questions

Where does the None actually come from?

Work backwards from the traceback to whatever produced the value. The usual sources are a function with a code path that returns nothing, a dict .get with no match, a regex that did not match, or a database query with no row.

Why do so many functions return None by accident?

Because a Python function with no return statement returns None implicitly, so any branch that falls off the end produces it. A missing return inside an if is the classic version of this bug.

What is the difference from 'has no attribute'?

Only the access style: subscriptable is square brackets, attribute is a dot. Both mean the same thing — the value is None and you expected an object.

How do I catch this earlier?

Type hints plus a checker such as mypy flag Optional values used without a guard, at the point the function is written rather than when the code runs. That moves the whole class of error from runtime to review.

Related in Errors