How to Fix: AttributeError: ‘NoneType’ object has no attribute ‘append’

3D illustration of a robot dropping a ball through a transparent ghost box, representing the NoneType object has no attribute append error.

This AttributeError NoneType append is a classic combination of two common problems: a NoneType error and a List method error.

It means: You are trying to use the .append() method, but the variable you’re using it on is None, not a list.

⚡ Quick Fix: AttributeError: ‘NoneType’ object has no attribute ‘append’ — Python Missing return Statement and In-Place Method Assignment Fix for List Building

Your variable holds None instead of a list — a function returned nothing on one of its code paths, and .append() has no list to attach to.

# WRONG — function returns None when user_id is 5 or below
def get_user_scores(user_id):
    if user_id > 10:
        return [90, 85, 100]
    else:
        return None              # None reaches the caller silently

scores = get_user_scores(5)
scores.append(40)                # AttributeError: 'NoneType' object has no attribute 'append'

# WRONG — .append() modifies in-place and returns None, assigning it kills the list
my_list = [1, 2, 3]
my_list = my_list.append(4)     # my_list is now None
my_list.append(5)               # AttributeError fires here

# RIGHT — always return [] instead of None when a list is expected
def get_user_scores(user_id):
    if user_id > 10:
        return [90, 85, 100]
    return []                    # empty list is safe to .append() on

scores = get_user_scores(5)
scores.append(40)
print(scores)                    # Output: [40]

# RIGHT — call .append() as a standalone statement, never assign its result
my_list = [1, 2, 3]
my_list.append(4)               # modifies my_list directly
print(my_list)                  # Output: [1, 2, 3, 4]

The two causes below explain exactly how None ends up where your list should be — trace it back to the source, not the crash line.

The Cause

This almost always happens when you call a function that was supposed to return a list, but it failed or had a code path that returned None instead.

Problem Code:

def get_user_scores(user_id):
    if user_id > 10:
        return [90, 85, 100]
    else:
        # This user has no scores, so we return nothing
        return None 

# 1. This works fine
high_scorer_list = get_user_scores(20)
high_scorer_list.append(99) # Appends to [90, 85, 100]

# 2. This crashes
low_scorer_list = get_user_scores(5) # This variable is now None
low_scorer_list.append(40)
# CRASH! AttributeError: 'NoneType' object has no attribute 'append'

The Fix: Always Return an Iterable (e.g., [])

The best fix is to make your function “safer.” A function that “gets a list” should always return a list, even if it’s an empty one.

Corrected Function:

def get_user_scores(user_id):
    if user_id > 10:
        return [90, 85, 100]
    else:
        # THE FIX: Return an empty list
        return []

Now, the code will run without crashing:

low_scorer_list = get_user_scores(5) # This variable is now []
low_scorer_list.append(40)
print(low_scorer_list) # Output: [40]

AttributeError: ‘NoneType’ object has no attribute ‘append’ — Two Sources of None, One Rule That Prevents Both

AttributeError: ‘NoneType’ object has no attribute ‘append’ fires at the .append() call — but the bug lives at the assignment that handed None to your variable. Fix the source, not the crash line.

Run print(type(your_variable)) directly above the .append() call. If it prints , trace the variable back through your code to the assignment that produced it.

Two sources generate None silently and cause this exact error.

A function with an incomplete return path. A function that returns a list on the happy path and returns None — explicitly or implicitly — on any other branch hands None to every caller that hits that branch. The fix is consistent return types: return [] on the no-data path, return [items] on the data path. Never let a function that callers treat as a list source return None on any branch.

def get_scores(user_id: int) -> list:
if user_id > 10:
return [90, 85, 100]
return [] # consistent — always a list, never None

The -> list type annotation enforces this at the function signature level. Type checkers like mypy flag any return path that hands back None when the annotation promises a list.

.append() assigned to a variable. my_list = my_list.append(4) overwrites my_list with None in one line. .append(), .extend(), .insert(), .remove(), .sort(), and .reverse() all return None — they modify the original list directly. Call every one of these as a standalone statement. If you need the modified list assigned to a new variable, use a list comprehension or slicing instead.

Safe list copy with modification

new_list = my_list + [4] # creates a new list — my_list untouched
new_list = [*my_list, 4] # unpacking alternative — same result

Similar Posts

Leave a Reply