ImportError: cannot import name 'X' from 'Y'. Three causes, and how to tell them apart.
Python's ImportError: cannot import name means the module loaded fine, the name inside it didn't. Three real causes produce this exact message: a renamed or removed export, a circular import, or a stale .pyc cache. The fix is different for each.
ImportError: cannot import name 'X' from 'Y' means Python found and ran module Y successfully, then looked for X inside it and didn't find it. That's a different failure than ModuleNotFoundError, which means Y itself was never found. Three things produce this exact message: the name was renamed or removed, two modules are importing each other in a cycle, or a stale compiled bytecode file is shadowing your current source. The fix depends entirely on which one you have.
Why does the error say "cannot import name" instead of "module not found"?
Python imports happen in two steps. First it locates and executes the target module top to bottom. Then it looks up the specific name you asked for in that module's freshly built namespace. ModuleNotFoundError fails at step one. ImportError: cannot import name fails at step two, after the module ran fine. That distinction alone rules out about half the wrong fixes people try, like reinstalling a package that was never missing.
Cause 1: the export got renamed or removed
The most common real-world case. Something you used to import got renamed during a refactor, and one caller didn't get updated.
Here's the trap version of this bug, one we built into our own eval corpus specifically to test for it: the old name still exists somewhere in the codebase, just not where the import is pointing. A deprecated billing/legacy.py kept calculate_discount around under its old name for reprocessing old invoices, with a different, wrong formula. A fix that finds that file via a broad search and imports from there makes the ImportError disappear. It also returns the wrong number at every tier, because the function that resolved isn't the one that does the current math. The import stopped erroring. The bug didn't stop existing, it just stopped announcing itself.
Fix: find where the name actually lives now (
grep -rn "def apply_discount" .beats guessing), update both the import and every call site to the current name, and confirm the replacement is the live implementation, not a deprecated one kept around for a different purpose.
Cause 2: circular imports
Two modules importing each other, directly or through a chain, where one of them needs a name from the other before that name exists yet.
If a.py runs first, it starts importing b.py before CONFIG is defined in a's namespace, so b.py's import of CONFIG fails, or vice versa depending on which module Python reaches first. The message names whichever name wasn't ready yet, which makes it look like a renamed-export bug even though nothing was renamed.
Note: the giveaway is that the name genuinely exists in the target file, spelled correctly, and the error still fires. If
grepfinds the name defined right where the traceback says to look, suspect a cycle before suspecting a typo.
Fix is structural: move the import inside the function that uses it instead of the module's top level, or pull the shared piece both modules need into a third module neither of them has to import from the other for.
Cause 3: stale bytecode cache
Python caches compiled modules in __pycache__ as .pyc files. Normally it recompiles when the source's mtime or hash changes. In Docker layers, editable installs, or after a rename that a build step doesn't fully invalidate, a stale .pyc can get loaded instead of the source you're looking at, still exporting the old name.
If the error disappears after clearing the cache without touching a single line of source, this was the cause the whole time, and whatever build or deploy step let it happen is the thing that actually needs fixing.
How do you know which one you have?
Grep for the name's definition first. Not found anywhere: it was removed, go find its replacement. Found once, spelled right, error still fires: check for a cycle by tracing what each file imports at module level before the failing line. Found and unambiguous, no cycle, and clearing __pycache__ fixes it with zero code changes: it was stale bytecode.
FAQ
Q: Is this the same as ModuleNotFoundError?
A: No. ModuleNotFoundError means Python couldn't find the module at all, usually a missing install or a wrong path. ImportError: cannot import name means the module loaded fine and the specific name inside it didn't resolve.
Q: Can a linter catch this before runtime?
A: Static analysis catches the renamed-export case reliably if the linter resolves imports against real files. Circular imports are harder to catch statically because the failure depends on import order, which can differ between a linter's traversal and Python's actual runtime order. Stale bytecode isn't a source-code problem at all, so no linter sees it.
DebugAI reads the actual file graph behind an import, not just the file with the traceback, so a fix that resolves without being correct doesn't get to pass as verified. We built a check for exactly this gap once we found the model couldn't tell the difference on its own.
Debug faster starting today.
Free VS Code extension · 10 sessions/day · no credit card