Python TypeError
Core Python Errors and Exceptions Error explained

Python TypeError: What It Means and How to Fix It

1Python TypeError: overview

A TypeError means Python was asked to do something with a value whose type doesn't support it, such as adding a number to text or calling something that isn't a function.

GoalBy the end you can read a TypeError message and its traceback, recognise the five most common causes and fix each one.

Before this lesson: Python Data Types, Python Functions

2Python TypeError: diagram

Python TypeError: What It Means and How to Fix ItWrong: str + intage = 25msg = "Age: " + age# TypeError: can only# concatenate str (not "int")# to strRight: convert firstage = 25msg = "Age: " + str(age)msg = f"Age: {age}"print(msg)# Age: 25str(age)
Python never converts a number to text for you when you use +. Convert it yourself with str(), or put it inside an f-string, which converts it automatically.

3Python TypeError: explained step by step

A TypeError means an operation was given a value of a type it can't work with. Python never guesses what you meant: it won't quietly turn 25 into "25" just because you put it next to some text. Instead it stops and tells you which types clashed.

What the message is telling you

The text after TypeError: names the operation and the types involved. can only concatenate str (not "int") to str reads as: "+ with a string on the left can only join another string, but you gave it an int."

Python
age = 25
try:
    print("Age: " + age)
except TypeError as err:
    print("TypeError:", err)

print("Age: " + str(age))   # fix 1: convert first
print(f"Age: {age}")        # fix 2: let an f-string convert

How to read the traceback

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    label = "Total: " + total
            ~~~~~~~~~~^~~~~~~
TypeError: can only concatenate str (not "int") to str
  1. Start with the last line: the error type and the types that clashed.
  2. Move up one line for the file and line number.
  3. The ^ marker points at the operator that failed, and the ~ marks the values on each side of it.
  4. Still unsure? Print type() of each value just before that line runs.

Common causes and how to fix them

1. Joining text and numbers. "Total: " + 42 fails. Use str(42) or an f-string. The reverse trips people up too: input() always returns a string, so convert with int() or float() before doing maths with it.

2. Calling something that isn't a function, giving 'int' object is not callable. You put () after a value. Usually a variable has replaced a built-in function (sum = 0, then later sum(prices)), or a * is missing: 2(3 + 4) should be 2 * (3 + 4). Rename the variable or add the operator.

3. The wrong number of arguments, giving greet() missing 1 required positional argument: 'name' or greet() takes 1 positional argument but 2 were given. Compare your call with the function's def line and pass exactly what it expects.

4. A function gave back None, giving 'NoneType' object is not subscriptable or unsupported operand type(s) for +: 'NoneType' and 'int'. The function has no return on that path, or you used the result of an in-place method such as list.sort(). Add the missing return, or use sorted(), which returns a new list.

5. A list used as a dictionary key, giving unhashable type: 'list'. Dictionary keys and set items must be values that can't change. Convert the list to a tuple: tuple(point).

Finding the culprit with type()

When a message mentions NoneType, the value came from somewhere that returned nothing. Checking the type tells you which variable to trace back:

Python
def get_discount(code):
    if code == "SAVE10":
        return 10
    # no return for other codes, so Python returns None

discount = get_discount("HELLO")
print(type(discount))
try:
    print(100 - discount)
except TypeError as err:
    print("TypeError:", err)

4Python TypeError: syntax

str(number)              # int/float -> str before joining text
int(text), float(text)   # str -> number before doing maths
f"Total: {number}"       # f-strings convert values for you
tuple(my_list)           # list -> tuple to use as a dict key
type(value)              # find out what a value really is
isinstance(value, str)   # check a type in an if statement

5Python TypeError: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
name = "Asha"
age = 25
quantity = "3"      # text, as if it came from input()
price = 2.5

try:
    print("Age: " + age)
except TypeError as err:
    print("TypeError:", err)

print("Age: " + str(age))
print(f"{name} is {age}")

try:
    total = quantity * price
except TypeError as err:
    print("TypeError:", err)

total = int(quantity) * price
print("Total:", total)
Expected outputTypeError: can only concatenate str (not "int") to str
Age: 25
Asha is 25
TypeError: can't multiply sequence by non-int of type 'float'
Total: 7.5

7Python TypeError: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-4Four variables. Note that quantity is the string "3", not the number 3. That's exactly what input() would give you.
  2. Line 6-9"Age: " + age tries to join a str and an int, so Python raises a TypeError. The except block catches it and prints the message, so the program keeps running.
  3. Line 11-12Two fixes: str(age) converts the number to text before joining, and the f-string converts whatever is inside {} automatically.
  4. Line 14-17A string can be repeated by a whole number ("3" * 2 is "33") but not by a float, so "3" * 2.5 raises a TypeError with a different message.
  5. Line 19-20int(quantity) turns the text into the number 3 first, so the multiplication works: 3 × 2.5 = 7.5.

8Python TypeError: common mistakes

Doing maths with the text from input()

✗ Wrong

count = input("How many tickets? ")
print("With a friend:", count + 1)
TypeError: can only concatenate str (not "int") to str

✓ Right

count = int(input("How many tickets? "))
print("With a friend:", count + 1)

input() always returns a string, even when the user types digits. Convert it with int() (or float()) straight away.

Using a built-in function's name for a variable

✗ Wrong

list = ["a", "b"]
letters = list("xyz")
TypeError: 'list' object is not callable

✓ Right

names = ["a", "b"]
letters = list("xyz")
print(letters)

The variable list has replaced Python's built-in list() function, so list(...) now tries to call your list. Choose a descriptive name like names and never reuse list, str, sum, max, input or print.

Using the result of list.sort()

✗ Wrong

scores = [70, 95, 82]
top = scores.sort()[-1]
TypeError: 'NoneType' object is not subscriptable

✓ Right

scores = [70, 95, 82]
top = sorted(scores)[-1]
print(top)

sort() sorts the list in place and returns None, so [-1] is applied to None. Use sorted(scores), which returns a new list, or simply max(scores).

9Python TypeError: exercises

Write your answer, then press Check. The checks run in your browser.

1. Fix the score message

Fix the bug Easy

This code should store "Your score is 87 points" in message and print it, but it raises a TypeError. Fix it without changing the value of score.

Your code
score = 87
message = "Your score is " + score + " points"
print(message)

2. Predict the mixed total

Predict the output Easy

Read the code and type exactly what it will print. Then press Check to compare.

Read this code
values = [10, "5", 2.5]
total = 0

for v in values:
    try:
        total = total + v
        print("added", v)
    except TypeError:
        print("skipped", repr(v))

print(total)

2 more exercises → 4 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

Why do I get a TypeError when I add a number to input()?

input() always returns a string, even if the user types 42. Adding 1 to "42" mixes str and int, so Python raises TypeError: can only concatenate str (not "int") to str. Convert the input first: int(input("Age: ")) or float(input("Price: ")).

What does 'NoneType' object is not subscriptable mean?

You used square brackets on a value that is None. It usually comes from a function that has no return statement on that path, or from an in-place method such as list.sort(), dict.update() or list.append(), which all return None. Print the variable's type and trace it back to where it was assigned.

What is the difference between TypeError and ValueError?

A TypeError means the kind of value is wrong, for example adding a str to an int. A ValueError means the type is fine but the content isn't, for example int("abc"): int() accepts strings, just not that one.

Further reading

10Next lesson

Up nextPython KeyError: What It Means and How to Fix ItA KeyError is raised when you use square brackets to ask a dictionary for a key it does not contain, like user["phone"]…

Related:
Python Data TypesPython Input and OutputPython Exceptions: try, except, else and finallyPython KeyError: What It Means and How to Fix It

← Python Exceptions: try, except, else and finally · All Errors and Exceptions lessons · Practise in the IDE