How to Fix: TypeError: ‘NoneType’ object is not callable

3D illustration of a user trying to use a phone that has vanished, representing the 'NoneType object is not callable' error.

The NoneType object is not callable error means you are trying to “call” a variable (by putting () after it) as if it were a function, but the variable is actually None.

⚡ Quick Fix: TypeError: ‘NoneType’ object is not callable — Python Missing return in Decorator and In-Place Method Assignment Fix

You put () after a variable that holds None — either a function stored None instead of a callable, or you assigned the result of an in-place method like .sort() to a variable and then tried to call it.

# WRONG — decorator returns None because it forgot to return the wrapper
def my_decorator():
    pass                   # no return — my_decorator hands None to the decorated function

@my_decorator
def say_hello():
    print("Hello")

say_hello()                # TypeError: 'NoneType' object is not callable

# WRONG — .sort() modifies in-place and returns None, not a callable
my_list = [3, 1, 2]
my_sorter = my_list.sort() # my_sorter is now None
my_sorter()                # TypeError: 'NoneType' object is not callable

# RIGHT — decorator must return the wrapper function
def my_decorator(func):
    def wrapper():
        print("Before")
        func()
        print("After")
    return wrapper         # return the wrapper, not None

@my_decorator
def say_hello():
    print("Hello")

say_hello()                # works

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

The two causes below explain exactly how None ends up where Python expects a callable — and how to trace it back to the assignment in both cases.

The Cause

This almost always happens when you think you have a function, but you actually have None. This can be for two main reasons.

1. A Function Forgot to return a Function

This is common in decorators or advanced code.

def my_decorator():
    # ... some logic ...
    # Whoops, forgot to return the wrapper function!
    pass

@my_decorator
def say_hello(): # 'say_hello' is now None
    print("Hello")

say_hello() # CRASH! TypeError: 'NoneType' object is not callable

2. A Variable You Think is a Function is None

You might misspell a variable name or, more commonly, a class method.

Problem Code:

my_list = [1, 2, 3]
# We want to sort the list, but we accidentally try to assign
# the .sort() method to a variable.
my_sorter = my_list.sort() # .sort() modifies IN-PLACE and returns None!

print(my_sorter) # Output: None
my_sorter()      # CRASH! 'NoneType' object is not callable

The Fix: Check your code! Find the variable you’re trying to call. print() its value just before the line that crashes. You’ll see that it’s None, and you can trace back why it’s not the function you were expecting.


TypeError: ‘NoneType’ object is not callable — Two Sources of None, One Diagnostic Move

TypeError: ‘NoneType’ object is not callable fires at the () — but the bug lives at the assignment. The variable held None before you ever added the parentheses.

Add print(type(your_variable)) directly above the crashing line. If it prints , trace the variable back to where it got assigned. The fix always lives at the source.

Two assignments produce None silently and cause this error.

A decorator or factory function that forgets return. A decorator receives a function, wraps it in a new function, and must return that new function. A decorator that ends with pass or has no return statement hands None back to Python — and Python assigns that None to the decorated function’s name. Add return wrapper as the last line of every decorator you write.

An in-place method assigned to a variable. list.sort(), list.reverse(), list.append(), dict.update(), and set.add() all return None — they modify the original object directly. Never assign their result to a variable. Call them as standalone statements and keep using the original object. If you need a sorted copy, use sorted(my_list) instead of my_list.sort() — sorted() returns a new list, not None.

In-place — modifies original, returns None

my_list.sort()
print(my_list) # sorted in place

Returns new object — assign this one

sorted_list = sorted(my_list)
print(sorted_list) # sorted copy

The callable() built-in gives you a fast runtime check before any suspicious call:

if callable(my_function):
my_function()
else:
print(f”Expected a function, got {type(my_function)}”)

Similar Posts

Leave a Reply