Python Error Guide: 'AttributeError: module has no attribute' — Cause, Fix, and Troubleshooting Guide
Fix Python 'AttributeError: module has no attribute': stop a local file shadowing a real module, fix typos, and handle symbols moved between versions.
- #python
- #automation
- #troubleshooting
- #errors
Stuck on this Bash & Python Automation error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
Python raises this when you access a name on a module that the module doesn’t define:
AttributeError: module 'json' has no attribute 'loads'
The module imported successfully, but the attribute you reached for isn’t there. When it’s a stdlib or well-known library complaining about a function that obviously exists (json.loads, requests.get), the near-certain cause is a local file shadowing the real module — a json.py of your own got imported instead. Other causes are a typo, a symbol that moved between versions, or accessing something defined later than the access.
Symptoms
- The message names the module and the missing attribute.
- The attribute plainly exists in the real library’s docs, yet Python insists it’s absent.
module.__file__points at a file in your project, not the stdlib/site-packages.- It broke after adding a new file to the project, or after upgrading a dependency.
Common Root Causes
- A local file shadows the module — e.g. your own
json.py,random.py, ortoken.pynext to the script is imported first, and it lacks the attribute. - A stale
.pycor__pycache__from a since-deleted shadowing file. - Typo or wrong casing in the attribute name.
- The symbol moved or was renamed between library versions.
- Circular/partial import — the module is mid-initialization and the attribute isn’t defined yet.
- Accessing a name defined later in the same module, or only under a conditional branch.
Diagnostic Workflow
The first and most decisive check — where did the module come from?
python3 -c "import json; print(json.__file__)"
# /usr/lib/python3.11/json/__init__.py <-- good (stdlib)
# /srv/app/json.py <-- BAD: your file is shadowing it
List the module’s real attributes:
python3 -c "import json; print([a for a in dir(json) if not a.startswith('_')])"
Look for a shadowing file and stale bytecode in your tree:
find . -name 'json.py' -o -name '__pycache__' -type d
Check the library version if a symbol may have moved:
python3 -c "import somelib; print(somelib.__version__, somelib.__file__)"
Example Root Cause Analysis
A parser script failed on a line that had worked for months:
AttributeError: module 'json' has no attribute 'loads'
json.loads unquestionably exists, so the module identity was suspect:
$ python3 -c "import json; print(json.__file__)"
/srv/ingest/json.py
A teammate had added a helper file named json.py to the ingest/ directory. Because that directory was on sys.path[0], import json picked up the local file — which had no loads — instead of the standard library. The fix is to rename the shadowing file and clear stale bytecode:
git mv ingest/json.py ingest/json_helpers.py
find . -name '__pycache__' -type d -exec rm -rf {} +
After renaming and updating the import in code, import json resolved to the stdlib again and json.loads worked. The rule: never name your own files after modules you import.
Prevention Best Practices
- Check
module.__file__first for any “obviously exists” attribute error — it exposes shadowing immediately. - Never name files after stdlib/third-party modules — avoid
json.py,random.py,email.py,logging.py,token.py,types.py. - Clear stale bytecode —
find . -name __pycache__ -type d -exec rm -rf {} +after deleting or renaming modules. - Pin and read changelogs — a moved/renamed symbol between versions needs a code update, not a workaround.
- Use absolute imports and packages so your module namespace is explicit and less collision-prone.
- Lint with Ruff/Pyflakes, which can flag some undefined-attribute and shadowing situations.
Quick Command Reference
python3 -c "import mod; print(mod.__file__)" # stdlib path or your file?
python3 -c "import mod; print(dir(mod))" # real attribute list
find . -name 'mod.py' # find a shadowing file
find . -name '__pycache__' -type d -exec rm -rf {} + # clear stale .pyc
python3 -c "import lib; print(lib.__version__)" # symbol moved between versions?
Related Guides
- Python Error Guide: ‘ImportError: cannot import name’ — the related failure when importing a specific symbol.
- Python Error Guide: ‘ModuleNotFoundError: No module named’ — when the module itself can’t be found.
- Bash & Python Error Guide: ‘TypeError: NoneType object is not subscriptable’ — another attribute/access error from unexpected object identity.
Conclusion
AttributeError: module has no attribute means the module loaded but the name you reached for isn’t defined on it. When the attribute obviously exists in the real library, check module.__file__ — a local file shadowing the module is the overwhelming cause. Rename any file that collides with a module you import, clear stale __pycache__, and for symbols that vanished between releases, pin versions and read the changelog. Explicit, non-colliding module names keep this error away.
Fixed it? Get 500 Bash & Python Automation & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.