Quick summary
Summarize this blog with AI
TypeError: 'type' object is not subscriptable means Python hit square brackets on a class or type object that does not support subscription. In real projects, this usually happens for one of four reasons: you indexed a class instead of an instance, you used list[str] or dict[str, int] on Python 3.8 or earlier, you wrote square brackets when you meant parentheses, or you subscripted a custom class that never implemented the right special method.
If you want the short version, start by checking the line that raised the exception and ask one question: am I using [] on a class, not on a list, dict, tuple, or another object that actually supports subscription? In many cases, that single check is enough to fix the bug in under a minute.
Quick answer
These are the fastest fixes for the most common versions of this error:
- If you wrote
MyClass[0], create an instance first:MyClass()[0]only works if the instance supports__getitem__(). - If you wrote
list[str],dict[str, int], ortype[User]on Python 3.8 or earlier, switch totyping.List,typing.Dict, ortyping.Type, or upgrade to Python 3.9+. - If you wrote
my_function[0], you probably meantmy_function()[0]. - If you want a custom object to support
obj[index], implement__getitem__(). If you want a class to supportMyClass[T], implement__class_getitem__()or inherit fromtyping.Generic.
# Common fix when you indexed the class instead of the instance
class Numbers:
def __getitem__(self, index):
return [10, 20, 30][index]
# Wrong
Numbers[0]
# Right
Numbers()[0]
What the error means
In Python, an object is subscriptable if it can be used with square brackets, like obj[0] or obj["name"]. Lists, tuples, dictionaries, strings, and many other built-in containers are subscriptable. They either expose __getitem__() directly or are implemented in C with equivalent behavior.
The important detail here is the word type in the exception. Python is telling you that the thing on the left side of the brackets is a class object, not a normal container instance. That is why the message is not 'list' object is not subscriptable or 'int' object is not subscriptable. It is specifically complaining that a type object, meaning a class, does not know how to handle the brackets you used.
This distinction matters because the fix depends on whether you meant one of these two patterns:
instance[index], which relies on__getitem__()ClassName[T], which relies on__class_getitem__()and is common in type hints and generic classes
Common causes and how to fix each one
You indexed a class instead of an instance
This is the most literal form of the error. You created a class with subscriptable instances, but then used brackets on the class itself.
class Team:
def __init__(self):
self.members = ["Ana", "Ben", "Chris"]
def __getitem__(self, index):
return self.members[index]
# Wrong
Team[0]
# Right
Team()[0]
If your class has __getitem__(), the instance can be subscripted. The class usually cannot. When you see this error, print the variable before the brackets and confirm whether it is the class object or an instance created from that class.
You used Python 3.9-style generic syntax on Python 3.8 or earlier
This is one of the highest-intent variants behind the keyword typeerror: 'type' object is not subscriptable. Code like this is valid in Python 3.9 and newer:
names: list[str] = ["Ada", "Grace"]
scores: dict[str, int] = {"sql": 10}
owner: type[int]
But on Python 3.8 and earlier, built-in collections and type are not runtime generics in the same way. That means code such as list[str] can raise TypeError: 'type' object is not subscriptable. The safe fix on older versions is to import those types from the official typing module:
from typing import Dict, List, Type
names: List[str] = ["Ada", "Grace"]
scores: Dict[str, int] = {"sql": 10}
owner: Type[int]
Python 3.9 added built-in generic support through PEP 585. So if you copied a modern tutorial and your environment is still on 3.8, version mismatch may be the whole problem.
You used square brackets when you meant parentheses
This bug looks small, but it happens often when you are moving quickly or refactoring code. Brackets index an existing object. Parentheses call a function and return a value.
def get_rows():
return [["a", 1], ["b", 2]]
# Wrong
get_rows[0]
# Right
get_rows()[0]
If the traceback points to a function name followed by brackets, fix the function call first. After that, subscript the return value if needed.
You subscripted a custom class that is not generic
If you are writing a framework, data structure, or typed utility, you may intentionally want syntax like Box[int]. That syntax only works when the class supports class-level subscription.
class Box:
pass
# Raises TypeError
Box[int]
There are two common ways to fix this:
- Use
typing.Genericwhen you are defining a generic type for annotations. - Implement
__class_getitem__()if you really need custom runtime behavior.
from typing import Generic, TypeVar
T = TypeVar("T")
class Box(Generic[T]):
def __init__(self, value: T):
self.value = value
Box[int]
The Python data model documentation covers the difference between __getitem__() and __class_getitem__() in more detail if you need the low-level behavior.
Why list[str] works in Python 3.9+ but fails in Python 3.8
This version split confuses a lot of developers because the code looks perfectly reasonable. Starting with Python 3.9, standard collections like list, dict, tuple, and even type gained support for generic parameterization at runtime. That is why list[str] now works in ordinary code.
On Python 3.8 and earlier, that syntax is not broadly available in runtime contexts. In practice, the easiest rule is this:
- Python 3.9 and newer: use
list[str],dict[str, int], andtype[User] - Python 3.8 and earlier: use
List[str],Dict[str, int], andType[User]fromtyping
import sys
print(sys.version)
If you are debugging code from a shared repo, a copied Stack Overflow answer, or a tutorial written for a newer interpreter, always check the Python version before changing anything else. That one line can save a lot of wasted effort.
How to debug this error quickly
When you need to move fast, use this checklist:
- Read the exact line in the traceback. Find the object directly to the left of
[]. - Print the object and its type. If you see
<class '...', you are working with a class object. - Check your Python version with
sys.version. - Decide whether you meant to index a container, call a function, or declare a type hint.
- If the object is custom, look for
__getitem__()or__class_getitem__().
print(value)
print(type(value))
If you need a broader refresher on Python exceptions and tracebacks, see our Python exceptions guide. If the failing code uses lists heavily, this Python list tutorial is also a useful reference.
Best practices to avoid this error in new code
You do not need defensive programming everywhere, but a few habits reduce the odds of seeing this exception again:
- Keep type hints aligned with your interpreter version. If a project is pinned to Python 3.8, do not mix in 3.9+ generic syntax.
- Use clear variable names so classes and instances are easy to distinguish.
team_clsandteamare harder to confuse than two variables with nearly identical names. - Write small tests around typed helpers and custom containers. If a class is supposed to support
obj[index]orClass[T], test that behavior directly. - Do not copy annotation syntax blindly from newer tutorials. Check the target Python version first.
In other words, this is usually not a complicated bug. It is a signal that the object on the left side of the brackets is not the one you think it is.
FAQ
Why do I get TypeError: 'type' object is not subscriptable with list[str]?
The most common reason is that you are running Python 3.8 or earlier. In those versions, built-in collections like list and dict do not support the newer generic syntax in normal runtime code. Use List[str] from typing or upgrade to Python 3.9+.
How do I fix this error in Python 3.8?
Replace built-in generic annotations such as list[str], dict[str, int], and type[User] with List[str], Dict[str, int], and Type[User] from typing. If the error is not related to type hints, confirm that you are subscripting an instance instead of a class.
Does this error mean the object is not iterable?
No. Iteration and subscription are related but different concepts. An object can be iterable without supporting direct indexing, and a custom object can support obj[index] without behaving like a full iterator. This specific error only tells you that the square-bracket operation is not supported for the object you used.
Can I make my own class support MyClass[T]?
Yes. For type-driven generic classes, the usual solution is to inherit from typing.Generic. For custom runtime behavior, you can implement __class_getitem__(). If you want instance-level indexing such as obj[0], implement __getitem__() instead.