TypeError

The operation does not work on that type at all — the message names the types involved, so read it for the one you did not expect (very often NoneType).

InheritsBaseException›Exception›TypeError
Type / value exceptionPython 3 (all)Live demo
TypeError(*args)
Raised by
'a' + 1, None[0], f(1) for f(a, b), len(5), {[1]: 2}
Message
names the types: unsupported operand type(s) for +: 'int' and 'str'
Quick fix
convert explicitly (str(n), int(s)) or check for None
Watch out
'NoneType' object … = a variable is None, often a method that returns nothing

Demo

Live evaluation
Add two values. Numbers mix freely, str only joins str — and which side the str is on changes the message.
Try:
Inputs
aint | float | strnumbers stay numbers
bint | float | strnumbers stay numbers
Code
'Total: ' + 'ten'
Result
'Total: ten'

Compare str + int with int + str: the same mistake gives two different messages. With the str on the left, str.__add__ refuses with can only concatenate str (not "int") to str; with the int on the left, int.__add__ and str.__radd__ both decline and Python reports unsupported operand type(s). In Handle, None is the wrong type (TypeError) while '4.5' is a str with a bad value (ValueError).

Constructor

NameTypeRequiredDescription
*argsobjectnoUsually one message string. str(e) is that string; with several arguments it is the repr of the args tuple.

Attributes

AttributeTypeMeaning
argstupleThe constructor arguments — normally a 1-tuple holding the message.
__traceback__tracebackWhere it was raised. The last frame is usually the line with the operator or call that got the wrong type.
__notes__list[str]Extra lines added with e.add_note(), printed after the message (Python 3.11+).

Common patterns

Convert at the boundary
Text from input(), files, env vars and query strings is always str. Convert it once, where it enters, not at every use.
port = int(os.environ.get('PORT', '8000'))
print('listening on ' + str(port))
Fail early with a clear TypeError
In your own API, check the type up front and name what you got. Accept the widest type that works (numbers.Real, collections.abc.Iterable) instead of one concrete class.
def scale(values, factor):
    if not isinstance(factor, (int, float)):
        raise TypeError(f'factor must be int or float, not {type(factor).__name__}')
    return [v * factor for v in values]
Guard against None
Most 'NoneType' object … errors come from a lookup or function that returned None. Check at the source instead of wrapping every use in try/except.
match = re.search(r'\d+', text)
if match is None:
    raise ValueError(f'no number in {text!r}')
number = int(match.group())
Return NotImplemented from operators
In __add__ and friends, return NotImplemented for types you do not handle; Python then tries the other operand and raises the standard TypeError only if both decline.
class Money:
    def __init__(self, cents):
        self.cents = cents
    def __add__(self, other):
        if not isinstance(other, Money):
            return NotImplemented
        return Money(self.cents + other.cents)

Examples

1. str + int
'Age: ' + 30
Returns
TypeError: can only concatenate str (not "int") to str
2. Fix: f-string or str()
age = 30 f'Age: {age}'
Returns
'Age: 30'
3. Method that returns None
nums = [3, 1, 2].sort() nums[0]
Returns
TypeError: 'NoneType' object is not subscriptable
4. Looping over None
def find_users(): pass # forgot to return for user in find_users(): pass
Returns
TypeError: 'NoneType' object is not iterable
5. Missing argument
def greet(name, greeting): return f'{greeting}, {name}' greet('Ann')
Returns
TypeError: greet() missing 1 required positional argument: 'greeting'
6. Too many arguments
def greet(name): return 'Hi ' + name greet('Ann', 'Bob')
Returns
TypeError: greet() takes 1 positional argument but 2 were given
7. Unhashable dict key
{[1, 2]: 'pair'}
Returns
TypeError: unhashable type: 'list'
8. Sorting mixed types
sorted([3, '10', 2])
Returns
TypeError: '<' not supported between instances of 'str' and 'int'

Pitfalls

1. list.sort() returns None
In-place methods (sort, append, reverse, update) return None. Assigning their result replaces your data with None, and the TypeError appears one line later.
nums = nums.sort()
nums = [3, 1, 2]
nums = nums.sort()
nums[0]
TypeError: 'NoneType' object is not subscriptable
sorted() returns a list
nums = [3, 1, 2]
nums = sorted(nums)
nums[0]
1
2. Shadowing a built-in
A variable named list, str, dict, sum or input hides the built-in for the rest of the module; calling it later gives 'X' object is not callable.
str = …
str = 'hello'
str(42)
TypeError: 'str' object is not callable
Different name
text = 'hello'
str(42)
'42'
3. input() always returns str
Numbers typed by the user, read from a file or from os.environ arrive as text. Convert before doing arithmetic.
Arithmetic on text
age = '30'  # from input()
age + 1
TypeError: can only concatenate str (not "int") to str
int() first
age = '30'  # from input()
int(age) + 1
31
4. Calling a method on the class
Calling through the class instead of an instance means nothing is passed for self — Python reports it as a missing argument.
Cart.total()
class Cart:
    def total(self):
        return 0

Cart.total()
TypeError: Cart.total() missing 1 required positional argument: 'self'
Cart().total()
class Cart:
    def total(self):
        return 0

Cart().total()
0

When to use

Use it
  • Raising it when a caller passes an argument of the wrong type to your function
  • Catching it around duck-typed code that may receive unsupported objects
  • Returning NotImplemented from operator methods so Python raises it for you
Reach for something else
  • The type is right but the value is bad (negative size, bad string) → ValueError
  • A required attribute or method is missing on an object → AttributeError
  • Wrapping big blocks in except TypeError — it also hides real bugs inside

Notes

CPython impl
Objects/abstract.c — binary_op1() tries a.__add__ then b.__radd__; if both return NotImplemented, the "unsupported operand type(s)" message is built from both type names
str on the left
str.__add__ raises its own message first: can only concatenate str (not "int") to str
Catch via
except TypeError, or except Exception. It has no built-in subclasses.
Rule of thumb
Wrong kind of object → TypeError. Right kind, unacceptable value → ValueError.

FAQ

You used + between a str and a number, e.g. 'Total: ' + 5. Python never converts automatically. Use an f-string (f'Total: {n}'), str(n), or print('Total:', n) — print converts each argument for you.