TypeError: object is not subscriptable (tested)

TypeError: '<type>' object is not subscriptable means square-bracket indexing (obj[key] or obj[i]) was used on a value whose type has no __getitem__ method — lists, dicts, strings and tuples support it; plain numbers, most custom classes, and None don't. The type named in quotes is always the real culprit's type, which is the fastest way to tell these apart.

1. Five reproduced causes, same error shape

Different values trigger it, but the message always names the actual type that lacks __getitem__:

CodeExact error (Python 3.13.5)
x = [3,1,2].sort(); x[0]TypeError: 'NoneType' object is not subscriptable
x = 5; x[0]TypeError: 'int' object is not subscriptable
x = 5.5; x[0]TypeError: 'float' object is not subscriptable
class Foo: pass
Foo()[0]
TypeError: 'Foo' object is not subscriptable
x = some_function; x[0] (missing ())TypeError: 'function' object is not subscriptable

The fix is always the same shape: figure out why the value isn't the list, dict or string you expected, and correct that — adding [] support to a custom class is the only case where you'd change the type itself (section 4).

2. The single most common trigger: a method that mutates and returns None

Several built-in methods change a list or dict in place and return None on purpose, instead of returning the (now-modified) object. Chaining straight onto the result is the classic bug:

>>> x = [3, 1, 2].sort()
>>> x
>>> x[0]
Traceback (most recent call last):
  ...
TypeError: 'NoneType' object is not subscriptable

list.sort() sorts the list in place and returns None — the sorted data is in the original list, not in whatever x got assigned. list.append(), list.reverse(), dict.update() and set.add() all follow the same convention (confirmed: each returns None on this build). Fix by not reassigning the variable to the method's return value:

>>> nums = [3, 1, 2]
>>> nums.sort()      # mutates nums in place, no assignment needed
>>> nums[0]
1

The same root cause — a variable holding None instead of the expected value — also comes from a function with a missing or conditional return, or a dict.get(key) on a key that isn't there. For the full set of None-specific error wordings (iterate, call, len(), arithmetic, and more), see TypeError: 'NoneType' object is not subscriptable, in depth.

3. Treating a number as a sequence

Numbers don't support indexing at all, with or without None involved — this usually means the wrong variable name was indexed, or a loop reused a name that used to hold a list:

>>> x = 5
>>> x[0]
TypeError: 'int' object is not subscriptable
>>> y = 5.5
>>> y[0]
TypeError: 'float' object is not subscriptable

Fix: check the line where the variable was last assigned. A common pattern is a loop variable like for count in range(len(items)): followed by accidentally indexing count (an int) instead of items.

4. A custom class needs __getitem__ to support []

Plain objects of a class with no special methods don't support indexing by default:

>>> class Foo:
...     pass
>>> Foo()[0]
TypeError: 'Foo' object is not subscriptable

Adding a __getitem__ method fixes it — confirmed on this build:

>>> class Bar:
...     def __getitem__(self, i):
...         return i * 2
>>> Bar()[3]
6

This is the right fix only when the class is genuinely meant to act like a sequence or mapping. If it's just a plain data holder, the real bug is usually that code elsewhere expected a list or dict and got an instance of this class instead — fix the call site, not the class.

5. Forgetting to call a function: 'function' object is not subscriptable

Dropping the () leaves a reference to the function itself, not its return value:

>>> def get_items():
...     return [1, 2, 3]
>>> x = get_items
>>> x[0]
TypeError: 'function' object is not subscriptable

Fix: call it — x = get_items() — then x[0] works. The type name in the error ('function', not 'list' or 'NoneType') is the giveaway that a call was skipped.

6. The look-alike: TypeError: 'type' object is not subscriptable

This is a different message with a different cause: using generic subscript syntax on a builtin type for a type hint, like list[int], as a runtime expression. On this build (Python 3.13.5), it does not error at all:

>>> list[int]
list[int]
>>> type(list[int])
<class 'types.GenericAlias'>

list[int], dict[str, int] and similar builtin-generic syntax have worked at runtime since Python 3.9 (PEP 585), producing a types.GenericAlias object instead of raising. Per the Python 3.9 changelog (not measured on this box — no pre-3.9 interpreter was available): on Python 3.8 and earlier, the same expression raised TypeError: 'type' object is not subscriptable, because builtin types didn't support __class_getitem__ yet. If you see that exact message, the fix is either to upgrade to 3.9+, or to quote the annotation as a string ("list[int]") or import the equivalent from typing (typing.List[int]) for compatibility with older interpreters.

7. Fix checklist

For the None-specific deep dive (eight related messages: iterate, call, len(), arithmetic, in), see TypeError: 'NoneType' object is not subscriptable. If the value is a real list but the index is out of range, that's IndexError: list index out of range instead, not this error.

Frequently asked questions

What does TypeError: object is not subscriptable mean in Python?

It means obj[key] or obj[index] square-bracket syntax was used on a value whose type has no __getitem__ method - common culprits are None (from a method that mutates in place and returns None, or a missing return), plain numbers, custom classes without __getitem__, or a function reference missing its ().

Why does x = mylist.sort() followed by x[0] fail?

list.sort() sorts the list in place and returns None, not the sorted list. x ends up holding None, and None[0] raises TypeError: 'NoneType' object is not subscriptable. Use mylist.sort() on its own line, then index mylist directly - the same applies to append(), reverse(), dict.update() and set.add().

How do I make my own class support square-bracket indexing?

Define a __getitem__(self, key) method on the class. We confirmed on Python 3.13.5 that a class with no special methods raises TypeError: '<ClassName>' object is not subscriptable on obj[0], and adding __getitem__ resolves it immediately.

Is 'type' object is not subscriptable the same error as 'NoneType' object is not subscriptable?

No, different cause. 'type' object is not subscriptable came from using builtin-generic syntax like list[int] at runtime on Python 3.8 or earlier. We measured that Python 3.13.5 raises no error at all for list[int] (PEP 585, since Python 3.9) - it returns a types.GenericAlias object instead.

What is the difference between 'not subscriptable' and IndexError: list index out of range?

'Not subscriptable' means the value isn't a list/dict/sequence at all, so [] doesn't apply to its type - confirmed for None, int, float, and plain custom classes. IndexError: list index out of range means you do have a real list, just with an index past its length.

Written with AI assistance. Measured on 2026-10-03 with Python 3.13.5 on Linux using plain python3 one-liners. Every error below is copy-pasted output, not paraphrased. No Python &lt;3.9 interpreter was available to test on this box; that one claim is marked as unmeasured, per the Python changelog. PlainHeaders is our extension; Python is free.