ImportError: cannot import name 'TypeAliasType' from 'typing_extensions'
Nothing left your machine, and nothing about OpenAI is involved. This is CPython’s import system reporting that a module loaded successfully but does not contain a name something asked it for. There is no HTTP status, no request id, no token spend, and no model — so it is not an authentication problem, not a quota problem, not a malformed request, and not the API changing under you. The vendor’s name appears in your command only because the SDK is the first thing in your program deep enough to touch a typing backport; the failure is in your environment’s package resolution.
Read the path, not the package name
The message has a second half that almost everyone skips: after the module name, Python prints the file it actually imported. That path is the diagnosis, and it answers a question the package name cannot.
typing_extensions is a backport. It exists to hand libraries symbols that
newer interpreters have in the standard library, so that the same code runs on
older ones. TypeAliasType is one of those symbols. An import of it fails for
exactly one reason — the file Python loaded does not define it — and there are
two very different ways that happens:
- The installed release predates the symbol. The ordinary case. The path
points into your environment’s
site-packages, and a newer release is the fix. - The file Python loaded is not the package you think it is. A
typing_extensions.pysitting in your working directory or onPYTHONPATH, a vendored copy inside another package, a stale.pycleft behind, a system-level install ahead of your virtual environment onsys.path. Here the path points somewhere unexpected, and upgrading the package changes nothing at all, forever, because the import never resolves to the thing you upgraded.
The second case is why “just upgrade it” fails permanently for a minority of people while working instantly for everyone else. One glance at the printed path tells you which group you are in, and it costs nothing.
If you want it explicitly, ask the interpreter that is failing — the same one, in the same environment, not a fresh shell:
import typing_extensions, sys
print(typing_extensions.__file__, sys.executable)
A __file__ outside your environment is the whole answer. A sys.executable
you did not expect is the adjacent classic: pip and python resolving to
different environments, so everything you installed went somewhere the failing
process never looks.
Who actually asked for the symbol
The traceback’s last frame names typing_extensions, and its first frame names
your import openai. Neither is the useful one. The frame in between names the
package that demanded the new symbol, and that package is the one whose
requirement sets your floor.
That matters because it tells you which constraint to fix. Modern data-modelling and validation layers reach for the newest typing constructs, and the SDK depends on them rather than on the backport directly. Chasing the requirement up one level turns “something wants a newer typing_extensions” into “this named package wants it”, which is a constraint you can actually write down.
It also disposes of a plausible non-fix: upgrading Python does not help.
Libraries import these names from the backport unconditionally, precisely so they
do not have to branch on interpreter version. A newer interpreter carrying the
symbol in its own typing module is not consulted.
Is retrying useful?
No, and not in the weak sense — there is nothing here that could be retried.
The exception is raised while your module graph is being built. No request object exists, no client has been constructed, and no transport code has run. The SDK’s own retry policy — connection errors, 408, 409, 429 and 5xx responses, twice by default — operates on HTTP round trips, and none of it is reachable from here. If you have wrapped your API call in a retry decorator, that decorator is not even defined yet at the moment this fires.
Re-running the same interpreter against the same sys.path executes the same
resolution and raises the same ImportError at the same line. The only thing in
this story that can usefully be re-run is your installer, and re-running it
with the same constraints and a warm cache reproduces the same resolution too —
which is the trap covered in the next section.
The fix that works today and re-arms tomorrow
Upgrading the backport by hand clears the error immediately. It is also the version of this fix most likely to bring you back here, and the reason is worth understanding once.
An old release is usually installed because something asked for it — a
dependency with an upper bound, a lockfile, or a resolver decision made to
satisfy some other constraint. Upgrading it manually overrides that decision
without changing the constraint that produced it. Your environment now works and
pip considers it inconsistent, and the next thing that touches dependencies puts
it back: a pip install of anything else, a reinstall from requirements, a fresh
container build, a CI runner that starts from a clean cache.
The check that catches this takes one command:
pip check
A clean result means nothing is holding a conflicting requirement and your upgrade is stable. A reported conflict names the package that pinned you, and that package is where the real fix goes — upgrade it, or relax the bound deliberately and write down why.
There is a second tempting non-fix in the same family: pinning the OpenAI SDK back to an older release. It often works, because an older SDK carries a lower floor on the layers underneath it. You have then fixed a packaging problem by freezing an unrelated package, in a pin nobody will remember the reason for, and you have given up SDK changes you did want. If you must do it to ship today, pin with a comment naming this error.
Fix by what the path told you
- Path is in your environment, release is simply old — upgrade the backport
inside the environment the failing interpreter uses (
python -m pip, not a barepip), then runpip checkbefore you believe it. pip checknames a package holding a bound — that package is the fix. Upgrading it usually lifts the floor for free; if it cannot be upgraded, the constraint is a real one and you need a different combination, not a manual override.- Path points outside site-packages — you have a shadowing file. Rename or
delete it, clear stale bytecode, and check
PYTHONPATHand your working directory. No amount of installing fixes this one. sys.executableis not the environment you installed into — you have two environments. Install withpython -m pipfrom the same interpreter that fails, which makes the mismatch impossible by construction.- Works locally, fails in a container or CI — the resolution differs because the cache differs. Reproduce with a clean build, not an incremental one, or you are testing your cache rather than your manifest.
How to confirm it’s fixed
Two steps, and the second is the one that matters.
First, in the environment that was failing, start a fresh interpreter and import the SDK. A long-running process, a notebook kernel, or a dev server started before the install still holds the old module in memory and will keep reporting success or failure that has nothing to do with the current state of disk.
Second, prove it survives a rebuild. Install from your lockfile or requirements
into a brand-new virtual environment — or build the container image without the
cache — and import again there. A fix that only exists in your current
environment is not a fix, it is a local override with a delay fuse, and this
step is the difference between the two. Finish with pip check in the new
environment; a clean result is what tells you the constraint, and not just the
symptom, was addressed.
Related errors
- ChatCompletionMessageToolCallParam “cannot instantiate typing.Union” is the call-site half of the same reframe: also a plain Python error with the vendor’s name attached by coincidence, but there the import succeeded and the bug is in how a type was used.
- ERROR Invalid Version is the other shape of “a version string broke something you did not write” — useful when you need to work out which program produced a string and which one choked on it.
- openai.error.APIConnectionError is the first failure you can meet after the import works, and it is the clearest contrast: that one has a transport layer and a retry policy, this one has neither.
- The AI coding error triage tool sorts on the signals this page used: whether a status code exists, whether a request id exists, and whether anything ever left the process.