Python

How to Fix "TypeError: 'Required' Object Is Not Subscriptable" in Python

4 min read by DebuggedIt

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 in TypedDict to 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