TypeError: A Step By Step Troubleshooting Guide!

In this article, we’ll look at TypeError in Python, what are its causes, and how to fix them.

Troubleshooting any errors will include the following steps

  • Step#1: Understand the error and its causes
  • Step#2: Figure out which of the causes actually led to the error in your particular case
  • Step#3: Apply the Fix, test your code to confirm.
  • Step#4: Party!

Let us start by understanding the TypeError and its causes!

Understanding TypeError and its Causes

Instead of starting off with a definition, let’s take a look at an example!

myList = [1, 2, 4]
y = myList / 'a' 

This will produce a TypeError as shown below.

Traceback (most recent call last):
  File "main.py", line 2, in <module>
       y = myList / 'a'
TypeError: unsupported operand type(s) for /: 'list' and 'str'

The problem with our code is explained in the last line of the error text.

In simple words, it tells us that we cannot use the “/” operation between a list and a string, the list datatype simply does not support this operation.

This can be generalized as follows

TypeError is an exception that is raised by Python when an operation is applied to an object with no support for the said operation.

embeddedinventor.com

Type” in “TypeError” refers to “data type”, so next time you see a TypeError, remind yourself that there is some problem with the data type and the operation combo we have used!

Here the “operation” can refer to functions, methods, or operators like “+”, “-” etc (we will see some examples later in the article to understand better)

Following is an excerpt from the official python documenation

“Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.

Passing arguments of the wrong type (e.g. passing a list when an int is expected) should result in a TypeError”

Now that we learned what TypeErrors are and what causes them, fixing them is a fairly straightforward process.

There are a few tricks though, when you master those tricks they can save you lots of time and frustration in your Python journey! Let’s go ahead and see what those are next!

If you are in the first steps of your Python journey and you are not 100% clear about what exceptions are, I strongly recommend reading our article on Exceptions before proceeding with this one!

Exceptions in Python: Explained for Beginners!

There we have explained the concept of exceptions from a beginner perspective with the goal that you will leave away with an intuitive feeling on what exceptions actually are and what their place is in the world of programming!

Learning how to fix TypeError!

Here is a pro tip for you, to fix not just TypeError but any error in Python. Whenever your program crashes with an Exception, (take a deep breath and) have a look at the huge wall of error text that just got printed on your screen!

There is actually a lot of information contained in the error message, if you wish to learn the tricks then set aside 10mins of your time and read the following article!

Python: Details contained in an Exception

For visual learners out there we have also made an interesting video on that topic!

Coming back to the topic let’s see another simple example

print(1+"a")

Here we are attempting to add an integer with a string type. Since they are not compatible data or operands in this case, a TypeError would be raised and this will be our output:

Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    print(1+"a")
TypeError: unsupported operand type(s) for +: 'int' and 'str

To understand what went wrong, we need to focus on the last line of the error message. This is where the error type and the error message are displayed:

TypeError: unsupported operand type(s) for +: 'int' and 'str'

The message is short but crisp!

Here ‘int’ is short for the integer-type (the integer 1) and ‘str’ is short for string-type (the letter a)

It is saying that for the operation ‘+’ (addition), it does not support the operands ‘int’ and ‘str’ being used together.

So we’ll have to change that. Now if you’re having a hard time spotting where is the line or the code we’re supposed to change, simply refer to the error message again, as this is also usually indicated in the error message itself.

The first part of the error message does exactly that (called the stack trace). 

Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    print(1+"a")

It breaks down where it occurred exactly in the program and gives the line number and code. It might be easy to see where the error occurred by yourself in this program, but we can imagine how useful stack trace will be to pinpoint the error-causing statement in large and complex programs!

For visual learners:

Now since we know:

  1. What the problem is (cannot use int type and str type with each other in addition)
  2. Where it occurs (line 1, print(1+”a”))

We can either include two str type variables:

print("a"+"a")

Which results in an error-free output:

aa

Or we can do the opposite, using two int type variables:

print(1+1)

OUTPUT:

2

So look at the operands and the operator on the line pointed to you by the error text and in 90% of the cases you will intuitively know how to fix it!

For the remaining 10% of the cases, there is always Google and websites like ours!

The Root Cause Behind TypeErrors

If you are a keen reader, you are probably waiting for the explanation of the following line

Here the “operation” can refer to functions, methods, or operators like “+”, “-” etc (we will see some examples later in the article to understand better)

The time has come for us to explore this line with the help of some examples!

Let’s first look at an example where we pass in an argument of the wrong type.

def calcArea (length, breadth):
    return length * breadth

x = 10
y = 5
area = calcArea(x, y)
print(f"Area: {area} sq. units")

If everything runs the way we wish we will get the following output

Area:  50 sq. units

If we use the following values for x and y, what do you think will happen?

x = [1, 2, 3]
y = 5

You would think the code will crash with a TypeError, but in reality, the code will execute just fine and produce the following output!

Area:  [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] sq. units

which is basically the list [1, 2, 3] repeated 5 times!

This sort of “unexpected” behavior can happen all the time if the people who make the libraries are not careful, hence they would instead rewrite the calcArea function like this

def calcArea (length, breadth):
    if (type(length) is int) and (type(breadth) is int):
        return length * breadth
    else:
        raise TypeError

If you want to learn more about the “raise” keyword, here is an excellent article on that topic!

Python: Manually throw/raise an Exception using the “raise” statement

Now if we use normal inputs,

x = 10
y = 5
area = calcArea(x, y)
print(f"Area: {area} sq. units")

we get normal outputs

Area: 50 sq. units

If we use bad inputs

x = [1, 2, 3]
y = 5
area = calcArea(x, y)
print(f"Area: {area} sq. units")

The function will see if the argument “types” are okay and raise a TypeError if it finds a mismatch.

Traceback (most recent call last):
  File "main.py", line 9, in <module>
    area = calcArea(x, y)
  File "main.py", line 5, in calcArea
    raise TypeError
TypeError

These kinds of safeguards are implemented everywhere inside Python and in all the 3rd party libraries, and they are the main source of TypeErrors

Some Interesting Cases of TypeErrors

While researching for writing this article I found a few interesting ways to get into TypeErrors (inspired by source)

Case#1: Calling a non-callable object

The following code shows multiple ways of causing a TypeError.

#multiple ways to make this mistake

#calling a string
"hi"()

#calling an integer
5()

#calling a boolean value
bool_val = False
bool_val()

#calling a tuple
my_tuple = ("q","w","e","r","t","y")
my_tuple(5)

Though this might feel “interesting” and “different”, in reality, this example is in line with what we have learned so far

Here

Operator: Function call operator “( )”
Operand: string, int, etc
Expected type: function object (yes, functions are also objects in Python!)

The mismatch between them is causing the TypeError!

Case#2: Incorrect list index type

When calling a list and accessing its elements, the correct way to do it is by using indices. Doing it otherwise results in a TypeError:

#creating a list
my_list = [1, 2, 3]

#correct way to call a list:
my_list[0]

#incorrect ways to call a list;

#using a string:
my_list["first element"]

#using a tuple:
my_list[(1,2)]

#using a dict:
my_list[{0: 1}]

Here the mismatch is between

operator: Indexing operator “[ ]”
operand: list
expected type: integer

Case#3: Passing an incorrect number of arguments to functions

This is also an interesting one where you would not expect TypeError to be raised.

Consider the following simple function which takes in 3 arguments and returns their sum.

def my_func(a, b, c):
	return a + b + c

If I invoke this function with the correct number of arguments it will work as expected.

>>> my_func(1, 2, 3)
6

But if I send in “less than expected” number of arguments, that will result in a TypeError as shown below.

>>> my_func(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: my_func() missing 1 required positional argument: 'c'

The same happens when “more than expected” number of arguments are passed in.

>>> my_func(1, 2, 3, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: my_func() takes 3 positional arguments but 4 were given

Whatever we pass to a function is passed in the form of a Tuple, and Python always verifies that the tuple we pass in is of the right length before unpacking the tuple and assigning it to local variables, if it does not match a TypeError is raised as the tuple is not of the expected type as length is incorrect!

But why TypeError for incorrect length and not some other error? This was probably just a design choice picked by the architects of the Python programming language. This is just my theory though, the truth is even I do not know the answer to this question!

Figuring out exactly why TypeError is thrown in this scenario requires a deep dive into the very fabric of Python to see how exactly functions are implemented and why TypeError was the chosen exception in this scenario. I leave it to you to figure this one out!

Let us look at another one of these interesting cases with TypeErrors!

Case#4: Iterating on a non-iterative value

Iterating is when you are looping through every element in a collection or a dataset. This dataset has the property to be looped, which makes it an iterable.

Now if you tried to iterate and loop through a dataset that is not an iterable, you would inevitably raise a TypeError

#multiple ways to loop incorrectly:

#looping through an integer type
for i in 100:
    print(1)
    
#looping through a boolean type
for i in True:
    print(i)

Here the mismatch is between

Operator: “for
Operand: integer, boolean
Expected type: Iterable type

I guess the whole article turned out to be all about learning the concept behind type errors, but I am sure an avid reader like you should be able to apply this knowledge to your specific situation and solve the issue that got you to this article in the 1st place!

For the next step in your Python journey I invite you to master some of the most common errors you will run into in your daily life as a Python developer. We have compiled a list of just 7 exceptions that you need to focus on if you wish to gain mastery of Exceptions in Python!

7 Most Common In-Built Exceptions in Python!

If you are a visual learner here is a YouTube video that we made on that same topic!

And with that being said, I will end this article!

Congratulations on making it to the end of the article, not many have the perseverance to do so!

I hope you enjoyed reading this article and found it useful!

Feel free to share it with your friends and colleagues!

If your thirst for knowledge has not been quenched yet, here are some related articles that might spark your interest!

Related Articles

Python: Catch Exception and Print

7 Most Common In-Built Exceptions in Python!

Mutable and Immutable Data Types in python explain using examples

Thanks to Namazi Jamal for his contributions to writing this article!

Photo of author
Editor
Balaji Gunasekaran
Balaji Gunasekaran is a Senior Software Engineer with a Master of Science degree in Mechatronics and a bachelor’s degree in Electrical and Electronics Engineering. He loves to write about tech and has written more than 300 articles. He has also published the book “Cracking the Embedded Software Engineering Interview”. You can follow him on LinkedIn