LangChain issubclass TypeError: arg 1 must be a class Fix
The LangChain issubclass TypeError means a dependency in the import chain, usually pydantic, typing_extensions, typing_inspect or dataclasses_json, has a mismatched version. Fix it in a clean virtual environment on Python 3.10 or newer.
- The error is raised by a dependency, not by your code, and the last 3 to 5 traceback frames name the package that decides the fix.
- The most common cause is a polluted global environment where typing_extensions, pydantic or typing_inspect are out of step with each other or with LangChain.
- A fresh virtual environment on Python 3.10 to 3.12 fixes most cases in under two minutes.
- LangChain packages (langchain, langchain-core, langchain-community, langchain-openai) must be upgraded together, never one at a time.
- Confirm that python and pip belong to the same interpreter, and that no file or folder named langchain is shadowing the real package.
What does the LangChain issubclass TypeError mean, and why does it happen?
The LangChain issubclass TypeError ("issubclass() arg 1 must be a class") appears because Python's built-in issubclass(a, b) requires that a be a real class. Some library has called it on something that only looks like a type, for example a typing alias such as List[int], a Literal[...], an Annotated[...] or a TypedDict built by a different version of typing_extensions.
LangChain itself rarely does this. Importing it pulls in pydantic, typing_extensions and, in older releases, dataclasses_json and typing_inspect. One of those inspects type annotations at import time, and when its assumptions do not match the installed Python or sibling packages, it passes a non-class to issubclass() and crashes.
That is why the failure happens on the first line, import langchain, before any of your code runs. It is a dependency version conflict, not a bug in your project.
A plain pip install does not repair packages that were already in the environment. A global or long-lived environment often holds an old pydantic, an old typing_inspect, or a typing_extensions that another project pinned. The usual combinations are listed below.
| Situation | Why it breaks | Typical culprit |
|---|---|---|
| Python 3.8 or older with recent packages | The typing module lacks features newer libraries assume, so aliases are not classes | pydantic, typing_extensions |
| pydantic 1.10.x older than 1.10.8 with typing_extensions 4.6 or newer | typing_extensions changed how TypedDict and related types are built, and old pydantic mishandled them | pydantic/main.py, pydantic/fields.py |
| Old typing_inspect or dataclasses_json | They test generic aliases with issubclass() on interpreters where the alias is not a class | typing_inspect.py, dataclasses_json/* |
| pydantic v1 and v2 mixed, or a package built for the other major version | Models and validators expect the other major's internals | pydantic, langchain_core |
| Mismatched langchain, langchain-core, langchain-community versions | A newer package imports names or types the older one does not define consistently | langchain_core/* |
| Wrong interpreter (pip and python differ, Jupyter kernel differs) | You fixed one environment and ran another | Not a package, a path problem |
How do I read the traceback and diagnose the culprit?
Ignore the top of the traceback and read the last 3 to 5 frames above the TypeError line. The file path in those frames tells you which package made the failing call, and that decides the fix. Match the path against the table below.
Then run the diagnostic block in the same shell you use to run your project. It prints the interpreter, the relevant versions, any broken requirements, and which langchain file Python would import.
| Last frames mention | Meaning | Go to |
|---|---|---|
| pydantic/main.py, pydantic/fields.py, pydantic/typing.py | pydantic cannot handle a type from typing_extensions or an old Python | Fix 2 or Fix 4 in the upgrade section |
| typing_inspect.py | Old typing_inspect on a newer or older typing module | Fix 3 in the upgrade section |
| dataclasses_json/... | dataclasses-json calling typing_inspect or checking generics | Fix 3 in the upgrade section |
| langchain_core/..., langchain_community/... | Mixed package versions or a pydantic major mismatch | Fix 2, upgrading all langchain packages together |
| A path inside your own project, such as ./langchain.py | Your file is shadowing the library | The shadowing section below |
| A site-packages path from a different Python version than expected | Wrong interpreter | The interpreter mismatch part of the shadowing section |
which python; which pip
python --version
python -m pip --version
python -m pip list | grep -i -E 'langchain|pydantic|typing|dataclasses|marshmallow'
python -m pip check
python -c "import sys; print(sys.executable)"
# run from a different, empty directory to avoid local shadowing:
cd /tmp && python -c "import langchain, sys; print(langchain.__file__)"How do I fix it with a clean virtual environment?
This is Fix 1 and it resolves the majority of cases, because it removes every stale package at once. Use Python 3.10 to 3.12 if you have it.
The steps create a new environment and leave the old one untouched. Anything you install afterward will not exist in it, so reinstall your project's other requirements as well.
- Go to your project folder and create the environment: python3.11 -m venv .venv (use the interpreter version you want).
- Activate it: source .venv/bin/activate on Linux and macOS, or .venv\Scripts\activate on Windows.
- Upgrade the installer: python -m pip install -U pip.
- Install LangChain and the integration packages you actually use: python -m pip install -U langchain langchain-openai.
- Verify: python -c "import langchain; print(langchain.__version__)".
- Freeze what works into a new file, not your existing one: python -m pip freeze > requirements-lock.txt. Then merge the LangChain pins from requirements-lock.txt into your current requirements file by hand.
Which packages should I upgrade or pin, and does pydantic v1 vs v2 matter?
If you cannot start from scratch, upgrade the offending packages. For pydantic and typing_extensions errors, and for mixed LangChain packages (Fix 2), upgrade everything in one command so the resolver sees them together. If the trace points at typing_inspect or dataclasses_json (Fix 3), upgrade those and marshmallow, which dataclasses-json depends on.
If an upgrade breaks something else, pin a known-good set. Read versions from a working machine with pip freeze rather than guessing numbers.
Check the pydantic major with python -c "import pydantic; print(pydantic.VERSION)". Current LangChain is built for pydantic 2, and the old langchain.pydantic_v1 shim only exists for backward compatibility. Old code, or old third-party packages that import from it, can make a v1 model meet a v2 object and trigger type-inspection failures.
The modern distribution is split into langchain, langchain-core, langchain-community and provider packages such as langchain-openai. They release on related but separate schedules, so leaving one at an old version while upgrading another produces odd import errors. If another library in your project demands pydantic 1, put it in a separate environment rather than forcing two majors together.
# Fix 2: pydantic / typing_extensions / langchain family, together
python -m pip install -U typing_extensions pydantic langchain langchain-core langchain-community langchain-openai
# Fix 3: trace mentions typing_inspect or dataclasses_json
python -m pip install -U typing-inspect dataclasses-json marshmallow
# Check afterwards
python -m pip check
python -c "import langchain; print(langchain.__version__)"Why does it still fail: shadowing and kernel mismatches?
File shadowing: a file named langchain.py, or a folder named langchain without a matching package, in your working directory is imported instead of the library. The tell is langchain.__file__ pointing into your project. Rename the file or folder, and delete the stale __pycache__ directory next to it.
Interpreter mismatch: if which python and which pip point to different places, you installed into one environment and ran another. Fix it by using python -m pip consistently.
Jupyter and Conda: a notebook kernel can use a different environment from your terminal. In a cell, run import sys; print(sys.executable) and compare it with the terminal. To register the clean environment, run python -m pip install ipykernel and then python -m ipykernel install --user --name langchain-env, and select that kernel. Restart the kernel after any install, because already-imported modules stay in memory.
With Conda, prefer creating a new environment (conda create -n lc python=3.11) and use python -m pip inside it, rather than mixing conda and pip installs of pydantic or typing_extensions.
How do I prevent it from coming back?
Once the import works, record the exact versions in a new file: python -m pip freeze > requirements-lock.txt, or use a lock file from uv, Poetry or pip-tools. Do not point the redirect at an existing requirements.txt, since it would be overwritten. Recreate environments from the lock file instead of reinstalling loosely.
Upgrade deliberately: change one group of packages, run python -m pip check and your import test, and commit the new lock only if both pass.
Common questions
Does this error mean my LangChain code is wrong?
No. It is raised during import, before your logic runs, by a dependency such as pydantic or typing_inspect. Your code only matters if a local file named langchain.py is shadowing the real package.
Will pip install --upgrade langchain alone fix it?
Sometimes, but often not, because the conflicting package may be pydantic, typing_extensions or typing-inspect rather than LangChain. Upgrade them together with the langchain family, or use a clean virtual environment, which avoids the stale versions entirely.
Can I fix it on Python 3.8?
It is unreliable. Python 3.8 is end of life and current LangChain and pydantic releases assume newer typing behavior. Move to Python 3.10 to 3.12 and recreate the environment.
Why does it work in my terminal but fail in Jupyter?
The notebook kernel is probably running a different interpreter. Print sys.executable in both places, install packages with python -m pip into the kernel's environment, and restart the kernel afterward.
How do I confirm the fix worked?
Run python -c "import langchain; print(langchain.__version__)" from a directory other than your project, then python -m pip check. A printed version and the message No broken requirements found mean the import chain is healthy.