How to Fix "TypeError: 'Required' Object Is Not Subscriptable" in Python
Quick answer
Your code raises a subscriptable error pointing at something named Required, a name you probably never typed yourself. This specific error is a strong signal...
Your code raises a subscriptable error pointing at something named Required, a name you probably never typed yourself. This specific error is a strong signal you're working with Pydantic or FastAPI and have accidentally mixed up how a field's type annotation and default value are supposed to be written.
The Problem
Defining a model or route with a particular default-value pattern throws this exact error at runtime, often not even at the line where the mistake was written, but wherever the field is later accessed:
Traceback (most recent call last):
File "models.py", line 12, in <module>
class User(BaseModel):
File "models.py", line 14, in User
tags: List[Required[str]]
TypeError: 'Required' object is not subscriptable
It can also show up in a FastAPI route definition using a similar malformed pattern:
TypeError: 'Required' object is not subscriptable
File "routes.py", line 8, in get_items
def get_items(limit: int = Required[10]):
Why It Happens
Required is a sentinel value (not a generic type) used internally by Pydantic and FastAPI to represent "this field has no default and must be provided" β it isn't meant to be subscripted with square brackets the way a generic type like List[str] or Optional[int] is. This error appears almost exclusively from one specific category of mistake:
- Confusing
Required(a sentinel object) with a generic type hint, and trying to parameterize it as if it were one βRequired[str]instead of the correct pattern for marking a required field. - Copy-pasting a code snippet from an outdated tutorial or a different library version where the syntax for marking required fields with a specific type worked differently.
- Confusing
typing.Required(used inTypedDictto mark a specific key as required, valid starting in Python 3.11) with an unrelated Pydantic concept, since both libraries use the same word for a superficially similar but structurally different purpose.
The Fix
In Pydantic, a field is required simply by giving it a type annotation with no default value at all β there's no special Required[...] wrapper needed:
from pydantic import BaseModel
class User(BaseModel):
name: str # required β no default given
tags: list[str] # required β no default given
nickname: str = "" # optional β has a default
For FastAPI route parameters, a required query or path parameter similarly just needs a type annotation with no default:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items")
def get_items(limit: int): # required β no default value given
...
If you specifically need to use typing.Required, it belongs inside a TypedDict definition (Python 3.11+) to mark one key as required when the surrounding dict is otherwise using total=False β a very different context from a Pydantic model field:
from typing import TypedDict, Required, NotRequired
class Movie(TypedDict, total=False):
title: Required[str] # this key must always be present
year: NotRequired[int] # this key is optional
If your actual goal was marking a Pydantic field as required while also giving it additional validation metadata, use Field(...) with an ellipsis instead, which is Pydantic's own explicit way of saying "required, but here's some extra config":
from pydantic import BaseModel, Field
class User(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
Still Not Working?
If you're still seeing this error after removing any Required[...] usage, check whether you have a naming collision β a custom class or variable in your own codebase named Required that's shadowing the one imported from typing or a third-party library, causing Python to resolve the wrong object entirely:
python -c "from yourmodule import Required; print(Required)"
<class 'yourmodule.Required'> # this is YOUR class, not typing.Required
If this reveals a naming collision, rename your own class to something unambiguous, or use an explicit import alias to avoid the clash going forward:
from typing import Required as TypingRequired