Craftstack Academy
Python

Python TypeError: unsupported operand type(s) for -: 'int' and 'str' (or 'str' and 'int')

· Updated · 5 min read

You wrote a short program that asks for your birth year and works out your age. You type 2002, press Enter, and Python stops with this:

Terminal
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    age = 2026 - year
          ~~~~~^~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'str'

This is one of the most common errors in a first Python program. The fix is one word, but it's worth understanding why it happens, because the same idea comes back again and again.

Here is the program:

main.py
name = input("Your name? ")
year = input("Born in? ")
age = 2026 - year
print("Hi", name, "- you are", age)

What the error means

Read the last line of the error from the left:

  • TypeError: the problem is the type of a value, not its spelling.
  • unsupported operand type(s) for -: the minus sign got values it can't work with.
  • 'int' and 'str': the value on the left is an int (a whole number, 2026) and the value on the right is a str (a string, which means text).

Python can subtract a number from a number. It can't subtract text from a number, and it doesn't guess that the text "2002" was meant as a number.

The lines above the last one tell you where it happened: line 3 of main.py. The ^ mark points at the minus sign. (Python 3.11 and newer draw that mark; older versions only show the line.)

Why year is text

input() always gives back a string, even when you type only digits. You can check it yourself with type():

python
year = input("Born in? ")
print(type(year))
Terminal
Born in? 2002
<class 'str'>

So year holds the text "2002", not the number 2002. To Python those are as different as the word "five" and the number 5.

The fix: turn the text into a number

Wrap the input() in int():

main.py
name = input("Your name? ")
year = int(input("Born in? "))
age = 2026 - year
print("Hi", name, "- you are", age)
Terminal
Your name? Lena
Born in? 2002
Hi Lena - you are 24

Read the new line from the inside out: input() asks the question and gives back text, then int() turns that text into a whole number. Now both sides of the minus sign are numbers.

For numbers with a decimal point, like a height of 1.75, use float() instead of int().

The same error with other operators, and the other order

The two types in the message are in the same order as in your code: the value left of the operator first, then the value right of it. So if the text is on the left, the message turns round:

python
year = "2002"
next_birthday = year - 1
Last line of the error
TypeError: unsupported operand type(s) for -: 'str' and 'int'

The symbol after for tells you which operator failed. With text on the left, you'll see the same message for division and floor division, and a slightly longer one for powers:

Last lines of the errors
TypeError: unsupported operand type(s) for /: 'str' and 'int'
TypeError: unsupported operand type(s) for //: 'str' and 'int'
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

And with a number on the left of a +, like 2026 + year, it's for +: 'int' and 'str'. You get the same message from sum() on a list of strings, such as sum(["72", "85"]), because sum adds the items up one by one, starting from the number 0.

The fix is the same every time: convert the text to a number before you calculate, with int() or float().

Three operators behave differently, so watch out for them:

  • year + 1 with text on the left gives can only concatenate str (not "int") to str (see below).
  • year % 2 gives the puzzling TypeError: not all arguments converted during string formatting, because % after a string means "fill in this text", not "remainder".
  • year * 2 gives no error at all: it prints 20022002. Multiplying text by a whole number repeats the text. (Two strings, like "5" * "3", do fail: can't multiply sequence by non-int of type 'str'.)

If the message says 'NoneType' instead of 'str', the value isn't text but nothing: often a function that prints its result instead of returning it.

Two errors you may meet next

can only concatenate str (not "int") to str

This is the same problem the other way round. + between two strings joins them, but here one side is a number:

python
print("Born in " + 2002)
Last line of the error
TypeError: can only concatenate str (not "int") to str

Either let print() put the pieces together with commas, print("Born in", 2002), or turn the number into text first with str(2002).

ValueError: invalid literal for int() with base 10

int() only works when the text really is a whole number. If someone types a word, the conversion fails:

Terminal
Your name? Lena
Born in? nineteen
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    year = int(input("Born in? "))
           ^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'nineteen'

This one isn't a mistake in your code: it's input your program didn't expect. Handling it with try and except is the topic of Error Handling in Python Course 3.

How to read any TypeError

  1. Find the line number in the traceback, and the ^ mark under the line.
  2. Look at the operator or function it points to: -, +, len() and so on.
  3. Read the two types the message names. If you're not sure which value is which, print type() of each.
  4. Convert one side so the types match: int(), float() or str().
Python

Why does 0.1 + 0.2 not equal 0.3 in Python?

Why Python prints 0.30000000000000004 for 0.1 + 0.2, why 0.1 + 0.2 == 0.3 is False, and the three fixes: round for display, math.isclose() instead of ==, and Decimal for money. With code you can run.

· 4 min read

Learn by writing the code yourself.

Twenty minutes with the tutor, right in your browser. No card, nothing to install.

Start the free trial
A session: the tutor's chat on the left, the code editor with a Java program and its output on the right