}

Fix Python AttributeError: 'X' object has no attribute 'Y' (2026)

AttributeError: 'NoneType' object has no attribute 'method'

An AttributeError means you tried to access an attribute or method that does not exist on that object. The most frequent version — 'NoneType' object has no attribute ... — means a function returned None and you called a method on it without checking first. The fix is to add a None check:

# BROKEN
result = get_user()
result.save()   # AttributeError if get_user() returned None

# CORRECT
result = get_user()
if result is not None:
    result.save()

Last updated: March 2026


The Full Error

Traceback (most recent call last):
  File "app.py", line 14, in process_order
    total = order.calculate_total()
AttributeError: 'NoneType' object has no attribute 'calculate_total'

The object type in the message tells you exactly what you have (NoneType, str, int, list, etc.). The attribute name tells you what you were trying to access. Together they point directly to the bug.


Cause 1: Function Returns None When Item Is Not Found

This is the single most common source of AttributeError. A lookup or query function returns None on failure, but the calling code assumes it always returns a real object.

Before (broken)

def find_order(order_id):
    for order in orders:
        if order.id == order_id:
            return order
    # implicit return None when not found

order = find_order(9999)
print(order.total)   # AttributeError: 'NoneType' object has no attribute 'total'

After (correct)

order = find_order(9999)
if order is None:
    print("Order not found")
else:
    print(order.total)

Cause 2: Wrong Type Passed In

A function expects one type but receives another. For example, passing None explicitly, or passing a plain dict where a class instance is expected.

def display_user(user):
    print(user.name)   # AttributeError if user is a dict

user = {"name": "Alice"}
display_user(user)   # dict has no .name — use user["name"]

Fix: either update display_user to accept dicts, or pass the correct type. Use isinstance to guard:

def display_user(user):
    if isinstance(user, dict):
        print(user.get("name"))
    else:
        print(user.name)

Cause 3: Typo in Attribute Name

Python attribute lookup is case-sensitive. A single character difference raises AttributeError.

import datetime
today = datetime.date.today()
print(today.Year)   # AttributeError: 'datetime.date' object has no attribute 'Year'
print(today.year)   # CORRECT — lowercase

If you are unsure of the exact attribute name, use dir() to list all attributes of an object:

print(dir(today))
# ['__class__', ..., 'day', 'month', 'replace', 'strftime', 'year', ...]

Cause 4: Missing self.attr Assignment in __init__

If you access self.attr in a method but never assign it in __init__, Python raises AttributeError when that method is called.

Before (broken)

class Dog:
    def __init__(self, name):
        self.name = name
        # forgot: self.tricks = []

    def add_trick(self, trick):
        self.tricks.append(trick)   # AttributeError: 'Dog' object has no attribute 'tricks'

After (correct)

class Dog:
    def __init__(self, name):
        self.name = name
        self.tricks = []   # initialize all instance attributes here

    def add_trick(self, trick):
        self.tricks.append(trick)

Always initialize every instance attribute in __init__, even if the initial value is None, [], or {}. This makes the class's interface explicit and prevents AttributeError from conditional initialization paths.


Cause 5: Module Attribute Errors

If you import a module and access a name that does not exist in it, you also get AttributeError.

import os
os.listdirectory(".")   # AttributeError: module 'os' has no attribute 'listdirectory'
os.listdir(".")         # CORRECT

This usually means a typo or an API that changed between versions. Check the official documentation or use dir(module) to list available names.


Cause 6: Overwriting a Built-in Name

If you assign to a name that shadows a module or built-in, you will get confusing AttributeError messages.

list = [1, 2, 3]        # overwrites the built-in list type
x = list.append(4)      # still works here...
y = list("hello")       # AttributeError — list is now [1,2,3], not the list class

Fix: rename your variable to avoid shadowing (items, my_list, etc.).


Using hasattr and getattr

When working with objects of unknown or variable structure, use hasattr and getattr to check and access attributes safely.

hasattr(obj, name) — check before accessing

if hasattr(user, "email"):
    print(user.email)
else:
    print("No email on file")

getattr(obj, name, default) — access with a fallback

email = getattr(user, "email", "[email protected]")
print(email)

getattr with three arguments never raises AttributeError — it returns the default if the attribute is missing.


Before/After: Real-World Example

A common pattern in web applications: a database query returns None when a record is not found, and the code does not check.

Before (broken)

from myapp.models import User

def get_user_email(user_id):
    user = User.objects.filter(id=user_id).first()
    return user.email   # AttributeError: 'NoneType' object has no attribute 'email'

After (correct)

def get_user_email(user_id):
    user = User.objects.filter(id=user_id).first()
    if user is None:
        return None
    return user.email

FAQ

Q: I am sure the object is not None, but I still get AttributeError.

A: Run print(type(obj)) right before the failing line to confirm the actual type. The object may have been reassigned to a different type earlier in the code, or a function may be returning a different type than you expect (e.g., a dict instead of a class instance).

Q: How do I catch AttributeError without letting it crash the program?

A: Use a try/except block, but only as a last resort — it is better to fix the root cause (missing None check, wrong type) than to silently swallow the error.

try:
    value = obj.attribute
except AttributeError:
    value = None

Q: AttributeError is raised inside a library I did not write. How do I fix it?

A: Read the traceback from top to bottom to find the last line in your own code. The library call is usually triggered by you passing the wrong type or a None value. Fix the value you pass in rather than modifying the library.


Related Pages