âčïž Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://realpython.com/python-traceback/ |
| Last Crawled | 2026-04-16 03:59:54 (1 day ago) |
| First Indexed | 2019-07-26 07:42:06 (6 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Understanding the Python Traceback â Real Python |
| Meta Description | In this step-by-step tutorial, you'll learn how to read and understand the information you can get from a Python traceback. You'll walk through several examples of tracebacks and see some of the most common tracebacks in Python. |
| Meta Canonical | null |
| Boilerpipe Text | Python prints a
traceback
when an exception is raised in your code. The traceback output can be a bit overwhelming if youâre seeing it for the first time or you donât know what itâs telling you. But the Python traceback has a wealth of information that can help you diagnose and fix the reason for the exception being raised in your code. Understanding what information a Python traceback provides is vital to becoming a better Python programmer.
By the end of this tutorial, youâll be able to:
Make sense of the next traceback you see
Recognize some of the more common tracebacks
Log a traceback successfully while still handling the exception
What Is a Python Traceback?
A traceback is a report containing the function calls made in your code at a specific point. Tracebacks are known by many names, including
stack trace
,
stack traceback
,
backtrace
, and maybe others. In Python, the term used is
traceback
.
When your program results in an exception, Python will print the current traceback to help you know what went wrong. Below is an example to illustrate this situation:
Here,
greet()
gets called with the parameter
someone
. However, in
greet()
, that
variable
name is not used. Instead, it has been misspelled as
someon
in the
print()
call.
When you run this program, youâll get the following traceback:
This traceback output has all of the information youâll need to diagnose the issue. The final line of the traceback output tells you what type of exception was raised along with some relevant information about that exception. The previous lines of the traceback point out the code that resulted in the exception being raised.
In the above traceback, the exception was a
NameError
, which means that there is a reference to some name (variable, function, class) that hasnât been defined. In this case, the name referenced is
someon
.
The final line in this case has enough information to help you fix the problem. Searching the code for the name
someon
, which is a misspelling, will point you in the right direction. Often, however, your code is a lot more complicated.
How Do You Read a Python Traceback?
The Python traceback contains a lot of helpful information when youâre trying to determine the reason for an exception being raised in your code. In this section, youâll walk through different tracebacks in order to understand the different bits of information contained in a traceback.
Python Traceback Overview
There are several sections to every Python traceback that are important. The diagram below highlights the various parts:
In Python, itâs best to read the traceback from the bottom up:
Blue box:
The last line of the traceback is the error message line. It contains the exception name that was raised.
Green box:
After the exception name is the error message. This message usually contains helpful information for understanding the reason for the exception being raised.
Yellow box:
Further up the traceback are the various function calls moving from bottom to top, most recent to least recent. These calls are represented by two-line entries for each call. The first line of each call contains information like the file name, line number, and module name, all specifying where the code can be found.
Red underline:
The second line for these calls contains the actual code that was executed.
There are a few differences between traceback output when youâre executing your code in the command-line and running code in the
REPL
. Below is the same code from the previous section executed in a REPL and the resulting traceback output:
Notice that in place of file names, you get
"<stdin>"
. This makes sense since you typed the code in through standard input. Also, the executed lines of code are not displayed in the traceback.
Specific Traceback Walkthrough
Going through some specific traceback output will help you better understand and see what information the traceback will give you.
The code below is used in the examples following to illustrate the information a Python traceback gives you:
Here,
who_to_greet()
takes a value,
person
, and either returns it or prompts for a value to return instead.
Then,
greet()
takes a name to be greeted,
someone
, and an optional
greeting
value and calls
print()
.
who_to_greet()
is also called with the
someone
value passed in.
Finally,
greet_many()
will iterate over the list of
people
and call
greet()
. If there is an exception raised by calling
greet()
, then a simple backup greeting is printed.
This code doesnât have any bugs that would result in an exception being raised as long as the right input is provided.
If you add a call to
greet()
to the bottom of
greetings.py
and specify a keyword argument that it isnât expecting (for example
greet('Chad', greting='Yo')
), then youâll get the following traceback:
Once again, with a Python traceback, itâs best to work backward, moving up the output. Starting at the final line of the traceback, you can see that the exception was a
TypeError
. The messages that follow the exception type, everything after the colon, give you some great information. It tells you that
greet()
was called with a keyword argument that it didnât expect. The unknown argument name is also given to you:
greting
.
Moving up, you can see the line that resulted in the exception. In this case, itâs the
greet()
call that we added to the bottom of
greetings.py
.
The next line up gives you the path to the file where the code exists, the line number of that file where the code can be found, and which module itâs in. In this case, because our code isnât using any other Python modules, we just see
<module>
here, meaning that this is the file that is being executed.
With a different file and different input, you can see the traceback really pointing you in the right direction to find the issue. If you are following along, remove the buggy
greet()
call from the bottom of
greetings.py
and add the following file to your directory:
Here youâve set up another Python file that is importing your previous module,
greetings.py
, and using
greet()
from it. Hereâs what happens if you now run
example.py
:
The exception raised in this case is a
TypeError
again, but this time the message is a little less helpful. It tells you that somewhere in the code it was expecting to work with a string, but an integer was given.
Moving up, you see the line of code that was executed. Then the file and line number of the code. This time, however, instead of
<module>
, we get the name of the function that was being executed,
greet()
.
Moving up to the next executed line of code, we see our problematic
greet()
call passing in an integer.
Sometimes after an exception is raised, another bit of code catches that exception and also results in an exception. In these situations, Python will output all exception tracebacks in the order in which they were received, once again ending in the most recently raise exceptionâs traceback.
Since this can be a little confusing, hereâs an example. Add a call to
greet_many()
to the bottom of
greetings.py
:
This should result in printing greetings to all three people. However, if you run this code, youâll see an example of the multiple tracebacks being output:
Notice the highlighted line starting with
During handling
in the output above. In between all tracebacks, youâll see this line. Its message is very clear, while your code was trying to handle the previous exception, another exception was raised.
You have seen the previous exception before, when you called
greet()
with an integer. Since we added a
1
to the list of people to greet, we can expect the same result. However, the function
greet_many()
wraps the
greet()
call in a
try
and
except
block. Just in case
greet()
results in an exception being raised,
greet_many()
wants to print a default greeting.
The relevant portion of
greetings.py
is repeated here:
So when
greet()
results in the
TypeError
because of the bad integer input,
greet_many()
handles that exception and attempts to print a simple greeting. Here the code ends up resulting in another, similar, exception. Itâs still attempting to add a string and an integer.
Seeing all of the traceback output can help you see what might be the real cause of an exception. Sometimes when you see the final exception raised, and its resulting traceback, you still canât see whatâs wrong. In those cases, moving up to the previous exceptions usually gives you a better idea of the root cause.
What Are Some Common Tracebacks in Python?
Knowing how to read a Python traceback when your program raises an exception can be very helpful when youâre programming, but knowing some of the more common tracebacks can also speed up your process.
Here are some common exceptions you might come across, the reasons they get raised and what they mean, and the information you can find in their tracebacks.
AttributeError
The
AttributeError
is raised when you try to access an attribute on an object that doesnât have that attribute defined. The Python documentation defines when this exception is raised:
Raised when an attribute reference or assignment fails.
(Source)
Hereâs an example of the
AttributeError
being raised:
The error message line for an
AttributeError
tells you that the specific object type,
int
in this case, doesnât have the attribute accessed,
an_attribute
in this case. Seeing the
AttributeError
in the error message line can help you quickly identify which attribute you attempted to access and where to go to fix it.
Most of the time, getting this exception indicates that you are probably working with an object that isnât the type you were expecting:
In the example above, you might be expecting
a_list
to be of type
list
, which has a method called
.append()
. When you receive the
AttributeError
exception and see that it was raised when you are trying to call
.append()
, that tells you that you probably arenât dealing with the type of object you were expecting.
Often, this happens when you are expecting an object to be returned from a function or method call to be of a specific type, and you end up with an object of type
None
. In this case, the error message line will read,
AttributeError: 'NoneType' object has no attribute 'append'
.
ImportError
The
ImportError
is raised when something goes wrong with an
import
statement. Youâll get this exception, or its subclass
ModuleNotFoundError
, if the module you are trying to
import
canât be found or if you try to import something from a module that doesnât exist in the module. The Python documentation defines when this exception is raised:
Raised when the import statement has troubles trying to load a module. Also raised when the âfrom listâ in
from ... import
has a name that cannot be found.
(Source)
Hereâs an example of the
ImportError
and
ModuleNotFoundError
being raised:
In the example above, you can see that attempting to import a module that doesnât exist,
asdf
, results in the
ModuleNotFoundError
. When attempting to import something that doesnât exist,
asdf
, from a module that does exists,
collections
, this results in an
ImportError
. The error message lines at the bottom of the tracebacks tell you which thing couldnât be imported,
asdf
in both cases.
IndexError
The
IndexError
is raised when you attempt to retrieve an index from a sequence, like a
list
or a
tuple
, and the index isnât found in the sequence. The Python documentation defines when this exception is raised:
Raised when a sequence subscript is out of range.
(Source)
Hereâs an example that raises the
IndexError
:
The error message line for an
IndexError
doesnât give you great information. You can see that you have a sequence reference that is
out of range
and what the type of the sequence is, a
list
in this case. That information, combined with the rest of the traceback, is usually enough to help you quickly identify how to fix the issue.
KeyError
Similar to the
IndexError
, the
KeyError
is raised when you attempt to access a key that isnât in the mapping, usually a
dict
. Think of this as the
IndexError
but for
dictionaries
. The Python documentation defines when this exception is raised:
Raised when a mapping (dictionary) key is not found in the set of existing keys.
(Source)
Hereâs an example of the
KeyError
being raised:
The error message line for a
KeyError
gives you the key that could not be found. This isnât much to go on but, combined with the rest of the traceback, is usually enough to fix the issue.
For an in-depth look at
KeyError
, take a look at
Python KeyError Exceptions and How to Handle Them
.
NameError
The
NameError
is raised when you have referenced a variable, module, class, function, or some other name that hasnât been defined in your code. The Python documentation defines when this exception is raised:
Raised when a local or global name is not found.
(Source)
In the code below,
greet()
takes a parameter
person
. But in the function itself, that parameter has been misspelled to
persn
:
The error message line of the
NameError
traceback gives you the name that is missing. In the example above, itâs a misspelled variable or parameter to the function that was passed in.
A
NameError
will also be raised if itâs the parameter that you misspelled:
Here, it might seem as though youâve done nothing wrong. The last line that was executed and referenced in the traceback looks good. If you find yourself in this situation, then the thing to do is to look through your code for where the
person
variable is used and defined. Here you can quickly see that the parameter name was misspelled.
SyntaxError
The
SyntaxError
is raised when you have incorrect Python syntax in your code. The Python documentation defines when this exception is raised:
Raised when the parser encounters a syntax error.
(Source)
Below, the problem is a missing colon that should be at the end of the function definition line. In the Python REPL, this syntax error is raised right away after hitting enter:
The error message line of the
SyntaxError
only tells you that there was a problem with the syntax of your code. Looking into the lines above gives you the line with the problem and usually a
^
(caret) pointing to the problem spot. Here, the colon is missing from the functionâs
def
statement.
Also, with
SyntaxError
tracebacks, the regular first line
Traceback (most recent call last):
is missing. That is because the
SyntaxError
is raised when Python attempts to parse your code, and the lines arenât actually being executed.
TypeError
The
TypeError
is raised when your code attempts to do something with an object that canât do that thing, such as trying to add a string to an integer or calling
len()
on an object where its length isnât defined. The Python documentation defines when this exception is raised:
Raised when an operation or function is applied to an object of inappropriate type.
(Source)
Following are several examples of the
TypeError
being raised:
All of the above examples of raising a
TypeError
results in an error message line with different messages. Each of them does a pretty good job of informing you of what is wrong.
The first two examples attempt to add strings and integers together. However, they are subtly different:
The first is trying to add a
str
to an
int
.
The second is trying to add an
int
to a
str
.
The error message lines reflect these differences.
The last example attempts to call
len()
on an
int
. The error message line tells you that you canât do that with an
int
.
ValueError
The
ValueError
is raised when the value of the object isnât correct. You can think of this as an
IndexError
that is raised because the value of the index isnât in the range of the sequence, only the
ValueError
is for a more generic case. The Python documentation defines when this exception is raised:
Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as
IndexError
.
(Source)
Here are two examples of
ValueError
being raised:
The
ValueError
error message line in these examples tells you exactly what the problem is with the values:
In the first example, you are trying to unpack too many values. The error message line even tells you that you were expecting to unpack 3 values but got 2 values.
In the second example, the problem is that you are getting too many values and not enough variables to unpack them into.
How Do You Log a Traceback?
Getting an exception and its resulting Python traceback means you need to decide what to do about it. Usually fixing your code is the first step, but sometimes the problem is with unexpected or incorrect input. While itâs good to provide for those situations in your code, sometimes it also makes sense to silence or hide the exception by logging the traceback and doing something else.
Hereâs a more real-world example of code that needs to silence some Python tracebacks. This example uses the
requests
library
. You can find out more about it in
Pythonâs Requests Library (Guide)
:
This code works well. When you run this script, giving it a URL as a
command-line argument
, it will call the URL and then print the HTTP status code and the content from the response. It even works if the response was an HTTP error status:
However, sometimes the URL your script is given to retrieve doesnât exist, or the host server is down. In those cases, this script will now raise an uncaught
ConnectionError
exception and print a traceback:
The Python traceback here can be very long with many other exceptions being raised and finally resulting in the
ConnectionError
being raised by
requests
itself. If you move up the final exceptions traceback, you can see that the problem all started in our code with line 5 of
urlcaller.py
.
If you wrap the offending line in a
try
and
except
block
, catching the appropriate exception will allow your script to continue to work with more inputs:
The code above uses an
else
clause with the
try
and
except
block. If youâre unfamiliar with this feature of Python, then check out the section on the
else
clause in
Python Exceptions: An Introduction
.
Now when you run the script with a URL that will result in a
ConnectionError
being raised, youâll get printed a
-1
for the status code, and the content
Connection Error
:
This works great. However, in most real systems, you donât want to just silence the exception and resulting traceback, but you want to log the traceback. Logging tracebacks allows you to have a better understanding of what goes wrong in your programs.
You can log the traceback in the script by importing the
logging
package
, getting a logger, and calling
.exception()
on that logger in the
except
portion of the
try
and
except
block. Your final script should look something like the following code:
Now when you run the script for a problematic URL, it will print the expected
-1
and
Connection Error
, but it will also log the traceback:
By default, Python will send log messages to standard error (
stderr
). This looks like we havenât suppressed the traceback output at all. However, if you call it again while redirecting the
stderr
, you can see that the logging system is working, and we can save our logs off for later:
Conclusion
The Python traceback contains great information that can help you find what is going wrong in your Python code. These tracebacks can look a little intimidating, but once you break it down to see what itâs trying to show you, they can be super helpful. Going through a few tracebacks line by line will give you a better understanding of the information they contain and help you get the most out of them.
Getting a Python traceback output when you run your code is an opportunity to improve your code. Itâs one way Python tries to help you out.
Now that you know how to read a Python traceback, you can benefit from learning more about some tools and techniques for diagnosing the problems that your traceback output is telling you about. Pythonâs built-in
traceback
module
can be used to work with and inspect tracebacks. The
traceback
module can be helpful when you need to get more out of the traceback output. It would also be helpful to learn more about some
techniques for debugging
your Python code and ways to
debug in IDLE
. |
| Markdown | [](https://realpython.com/)
- [Start Here](https://realpython.com/start-here/)
- [Learn Python](https://realpython.com/python-traceback/)
[Python Tutorials â In-depth articles and video courses](https://realpython.com/search?kind=article&kind=course&order=newest)
[Learning Paths â Guided study plans for accelerated learning](https://realpython.com/learning-paths/)
[Quizzes & Exercises â Check your learning progress](https://realpython.com/quizzes/)
[Browse Topics â Focus on a specific area or skill level](https://realpython.com/tutorials/all/)
[Community Chat â Learn with other Pythonistas](https://realpython.com/community/)
[Office Hours â Live Q\&A calls with Python experts](https://realpython.com/office-hours/)
[Live Courses â Live, instructor-led Python courses](https://realpython.com/live/)
[Podcast â Hear whatâs new in the world of Python](https://realpython.com/podcasts/rpp/)
[Books â Round out your knowledge and learn offline](https://realpython.com/products/books/)
[Reference â Concise definitions for common Python terms](https://realpython.com/ref/)
[Code Mentor âBeta Personalized code assistance & learning tools](https://realpython.com/mentor/)
[Unlock All Content â](https://realpython.com/account/join/)
- [More](https://realpython.com/python-traceback/)
[Learner Stories](https://realpython.com/learner-stories/) [Python Newsletter](https://realpython.com/newsletter/) [Python Job Board](https://www.pythonjobshq.com/) [Meet the Team](https://realpython.com/team/) [Become a Contributor](https://realpython.com/jobs/)
- [Search](https://realpython.com/search "Search")
- [Join](https://realpython.com/account/join/)
- [SignâIn](https://realpython.com/account/login/?next=%2Fpython-traceback%2F)
[Browse Topics](https://realpython.com/tutorials/all/)
[Guided Learning Paths](https://realpython.com/learning-paths/)
[Basics](https://realpython.com/search?level=basics)
[Intermediate](https://realpython.com/search?level=intermediate)
[Advanced](https://realpython.com/search?level=advanced)
***
[ai](https://realpython.com/tutorials/ai/) [algorithms](https://realpython.com/tutorials/algorithms/) [api](https://realpython.com/tutorials/api/) [best-practices](https://realpython.com/tutorials/best-practices/) [career](https://realpython.com/tutorials/career/) [community](https://realpython.com/tutorials/community/) [databases](https://realpython.com/tutorials/databases/) [data-science](https://realpython.com/tutorials/data-science/) [data-structures](https://realpython.com/tutorials/data-structures/) [data-viz](https://realpython.com/tutorials/data-viz/) [devops](https://realpython.com/tutorials/devops/) [django](https://realpython.com/tutorials/django/) [docker](https://realpython.com/tutorials/docker/) [editors](https://realpython.com/tutorials/editors/) [flask](https://realpython.com/tutorials/flask/) [front-end](https://realpython.com/tutorials/front-end/) [gamedev](https://realpython.com/tutorials/gamedev/) [gui](https://realpython.com/tutorials/gui/) [machine-learning](https://realpython.com/tutorials/machine-learning/) [news](https://realpython.com/tutorials/news/) [numpy](https://realpython.com/tutorials/numpy/) [projects](https://realpython.com/tutorials/projects/) [python](https://realpython.com/tutorials/python/) [stdlib](https://realpython.com/tutorials/stdlib/) [testing](https://realpython.com/tutorials/testing/) [tools](https://realpython.com/tutorials/tools/) [web-dev](https://realpython.com/tutorials/web-dev/) [web-scraping](https://realpython.com/tutorials/web-scraping/)
[Table of Contents](https://realpython.com/python-traceback/#toc)
- [What Is a Python Traceback?](https://realpython.com/python-traceback/#what-is-a-python-traceback)
- [How Do You Read a Python Traceback?](https://realpython.com/python-traceback/#how-do-you-read-a-python-traceback)
- [Python Traceback Overview](https://realpython.com/python-traceback/#python-traceback-overview)
- [Specific Traceback Walkthrough](https://realpython.com/python-traceback/#specific-traceback-walkthrough)
- [What Are Some Common Tracebacks in Python?](https://realpython.com/python-traceback/#what-are-some-common-tracebacks-in-python)
- [AttributeError](https://realpython.com/python-traceback/#attributeerror)
- [ImportError](https://realpython.com/python-traceback/#importerror)
- [IndexError](https://realpython.com/python-traceback/#indexerror)
- [KeyError](https://realpython.com/python-traceback/#keyerror)
- [NameError](https://realpython.com/python-traceback/#nameerror)
- [SyntaxError](https://realpython.com/python-traceback/#syntaxerror)
- [TypeError](https://realpython.com/python-traceback/#typeerror)
- [ValueError](https://realpython.com/python-traceback/#valueerror)
- [How Do You Log a Traceback?](https://realpython.com/python-traceback/#how-do-you-log-a-traceback)
- [Conclusion](https://realpython.com/python-traceback/#conclusion)
Mark as Completed
Share
Recommended Course
[ Getting the Most Out of a Python Traceback 21m · 5 lessons](https://realpython.com/courses/python-traceback/)

# Understanding the Python Traceback
by [Chad Hansen](https://realpython.com/python-traceback/#author)
Reading time estimate
25m
[8 Comments](https://realpython.com/python-traceback/#reader-comments)
[basics](https://realpython.com/tutorials/basics/) [python](https://realpython.com/tutorials/python/)
Mark as Completed
Share
Table of Contents
- [What Is a Python Traceback?](https://realpython.com/python-traceback/#what-is-a-python-traceback)
- [How Do You Read a Python Traceback?](https://realpython.com/python-traceback/#how-do-you-read-a-python-traceback)
- [Python Traceback Overview](https://realpython.com/python-traceback/#python-traceback-overview)
- [Specific Traceback Walkthrough](https://realpython.com/python-traceback/#specific-traceback-walkthrough)
- [What Are Some Common Tracebacks in Python?](https://realpython.com/python-traceback/#what-are-some-common-tracebacks-in-python)
- [AttributeError](https://realpython.com/python-traceback/#attributeerror)
- [ImportError](https://realpython.com/python-traceback/#importerror)
- [IndexError](https://realpython.com/python-traceback/#indexerror)
- [KeyError](https://realpython.com/python-traceback/#keyerror)
- [NameError](https://realpython.com/python-traceback/#nameerror)
- [SyntaxError](https://realpython.com/python-traceback/#syntaxerror)
- [TypeError](https://realpython.com/python-traceback/#typeerror)
- [ValueError](https://realpython.com/python-traceback/#valueerror)
- [How Do You Log a Traceback?](https://realpython.com/python-traceback/#how-do-you-log-a-traceback)
- [Conclusion](https://realpython.com/python-traceback/#conclusion)
[Remove ads](https://realpython.com/account/join/)
Recommended Course
[Getting the Most Out of a Python Traceback](https://realpython.com/courses/python-traceback/) (21m)
Python prints a **traceback** when an exception is raised in your code. The traceback output can be a bit overwhelming if youâre seeing it for the first time or you donât know what itâs telling you. But the Python traceback has a wealth of information that can help you diagnose and fix the reason for the exception being raised in your code. Understanding what information a Python traceback provides is vital to becoming a better Python programmer.
**By the end of this tutorial, youâll be able to:**
- Make sense of the next traceback you see
- Recognize some of the more common tracebacks
- Log a traceback successfully while still handling the exception
**Free Bonus:** [Click here to get our free Python Cheat Sheet](https://realpython.com/bonus/python-cheat-sheet-experiment/) that shows you the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.
## What Is a Python Traceback?
A traceback is a report containing the function calls made in your code at a specific point. Tracebacks are known by many names, including **stack trace**, **stack traceback**, **backtrace**, and maybe others. In Python, the term used is **traceback**.
When your program results in an exception, Python will print the current traceback to help you know what went wrong. Below is an example to illustrate this situation:
Python
```
```
Here, `greet()` gets called with the parameter `someone`. However, in `greet()`, that [variable](https://realpython.com/python-variables/) name is not used. Instead, it has been misspelled as `someon` in the [`print()`](https://realpython.com/python-print/) call.
**Note:** This tutorial assumes you understand Python exceptions. If you are unfamiliar or just want a refresher, then you should check out [Python Exceptions: An Introduction](https://realpython.com/python-exceptions/).
When you run this program, youâll get the following traceback:
Shell
```
```
This traceback output has all of the information youâll need to diagnose the issue. The final line of the traceback output tells you what type of exception was raised along with some relevant information about that exception. The previous lines of the traceback point out the code that resulted in the exception being raised.
In the above traceback, the exception was a `NameError`, which means that there is a reference to some name (variable, function, class) that hasnât been defined. In this case, the name referenced is `someon`.
The final line in this case has enough information to help you fix the problem. Searching the code for the name `someon`, which is a misspelling, will point you in the right direction. Often, however, your code is a lot more complicated.
[Remove ads](https://realpython.com/account/join/)
## How Do You Read a Python Traceback?
The Python traceback contains a lot of helpful information when youâre trying to determine the reason for an exception being raised in your code. In this section, youâll walk through different tracebacks in order to understand the different bits of information contained in a traceback.
### Python Traceback Overview
There are several sections to every Python traceback that are important. The diagram below highlights the various parts:
[](https://files.realpython.com/media/python_traceback_2.b27a4eb060a8.png)
In Python, itâs best to read the traceback from the bottom up:
1. **Blue box:** The last line of the traceback is the error message line. It contains the exception name that was raised.
2. **Green box:** After the exception name is the error message. This message usually contains helpful information for understanding the reason for the exception being raised.
3. **Yellow box:** Further up the traceback are the various function calls moving from bottom to top, most recent to least recent. These calls are represented by two-line entries for each call. The first line of each call contains information like the file name, line number, and module name, all specifying where the code can be found.
4. **Red underline:** The second line for these calls contains the actual code that was executed.
There are a few differences between traceback output when youâre executing your code in the command-line and running code in the [REPL](https://realpython.com/python-repl/). Below is the same code from the previous section executed in a REPL and the resulting traceback output:
Python
```
```
Notice that in place of file names, you get `"<stdin>"`. This makes sense since you typed the code in through standard input. Also, the executed lines of code are not displayed in the traceback.
**Note**: If you are used to seeing stack traces in other programming languages, then youâll notice a major difference in the way a Python traceback looks in comparison. Most other languages print the exception at the top and then go from top to bottom, most recent calls to least recent.
It has already been said, but just to reiterate, a Python traceback should be read from bottom to top. This is very helpful since the traceback is printed out and your terminal (or wherever you are reading the traceback) usually ends up at the bottom of the output, giving you the perfect place to start reading the traceback.
### Specific Traceback Walkthrough
Going through some specific traceback output will help you better understand and see what information the traceback will give you.
The code below is used in the examples following to illustrate the information a Python traceback gives you:
Python
```
```
Here, `who_to_greet()` takes a value, `person`, and either returns it or prompts for a value to return instead.
Then, `greet()` takes a name to be greeted, `someone`, and an optional `greeting` value and calls [`print()`](https://realpython.com/courses/python-print/). `who_to_greet()` is also called with the `someone` value passed in.
Finally, `greet_many()` will iterate over the list of `people` and call `greet()`. If there is an exception raised by calling `greet()`, then a simple backup greeting is printed.
This code doesnât have any bugs that would result in an exception being raised as long as the right input is provided.
If you add a call to `greet()` to the bottom of `greetings.py` and specify a keyword argument that it isnât expecting (for example `greet('Chad', greting='Yo')`), then youâll get the following traceback:
Shell
```
```
Once again, with a Python traceback, itâs best to work backward, moving up the output. Starting at the final line of the traceback, you can see that the exception was a `TypeError`. The messages that follow the exception type, everything after the colon, give you some great information. It tells you that `greet()` was called with a keyword argument that it didnât expect. The unknown argument name is also given to you: `greting`.
Moving up, you can see the line that resulted in the exception. In this case, itâs the `greet()` call that we added to the bottom of `greetings.py`.
The next line up gives you the path to the file where the code exists, the line number of that file where the code can be found, and which module itâs in. In this case, because our code isnât using any other Python modules, we just see `<module>` here, meaning that this is the file that is being executed.
With a different file and different input, you can see the traceback really pointing you in the right direction to find the issue. If you are following along, remove the buggy `greet()` call from the bottom of `greetings.py` and add the following file to your directory:
Python
```
```
Here youâve set up another Python file that is importing your previous module, `greetings.py`, and using `greet()` from it. Hereâs what happens if you now run `example.py`:
Shell
```
```
The exception raised in this case is a `TypeError` again, but this time the message is a little less helpful. It tells you that somewhere in the code it was expecting to work with a string, but an integer was given.
Moving up, you see the line of code that was executed. Then the file and line number of the code. This time, however, instead of `<module>`, we get the name of the function that was being executed, `greet()`.
Moving up to the next executed line of code, we see our problematic `greet()` call passing in an integer.
Sometimes after an exception is raised, another bit of code catches that exception and also results in an exception. In these situations, Python will output all exception tracebacks in the order in which they were received, once again ending in the most recently raise exceptionâs traceback.
Since this can be a little confusing, hereâs an example. Add a call to `greet_many()` to the bottom of `greetings.py`:
Python
```
```
This should result in printing greetings to all three people. However, if you run this code, youâll see an example of the multiple tracebacks being output:
Shell
```
```
Notice the highlighted line starting with `During handling` in the output above. In between all tracebacks, youâll see this line. Its message is very clear, while your code was trying to handle the previous exception, another exception was raised.
**Note**: Pythonâs feature of displaying the previous exceptions tracebacks were added in Python 3. In Python 2, youâll only get the last exceptionâs traceback.
You have seen the previous exception before, when you called `greet()` with an integer. Since we added a `1` to the list of people to greet, we can expect the same result. However, the function `greet_many()` wraps the `greet()` call in a `try` and `except` block. Just in case `greet()` results in an exception being raised, `greet_many()` wants to print a default greeting.
The relevant portion of `greetings.py` is repeated here:
Python
```
```
So when `greet()` results in the `TypeError` because of the bad integer input, `greet_many()` handles that exception and attempts to print a simple greeting. Here the code ends up resulting in another, similar, exception. Itâs still attempting to add a string and an integer.
Seeing all of the traceback output can help you see what might be the real cause of an exception. Sometimes when you see the final exception raised, and its resulting traceback, you still canât see whatâs wrong. In those cases, moving up to the previous exceptions usually gives you a better idea of the root cause.
[Remove ads](https://realpython.com/account/join/)
## What Are Some Common Tracebacks in Python?
Knowing how to read a Python traceback when your program raises an exception can be very helpful when youâre programming, but knowing some of the more common tracebacks can also speed up your process.
Here are some common exceptions you might come across, the reasons they get raised and what they mean, and the information you can find in their tracebacks.
### `AttributeError`
The `AttributeError` is raised when you try to access an attribute on an object that doesnât have that attribute defined. The Python documentation defines when this exception is raised:
> Raised when an attribute reference or assignment fails. [(Source)](https://docs.python.org/3/library/exceptions.html#AttributeError)
Hereâs an example of the `AttributeError` being raised:
Python
```
```
The error message line for an `AttributeError` tells you that the specific object type, `int` in this case, doesnât have the attribute accessed, `an_attribute` in this case. Seeing the `AttributeError` in the error message line can help you quickly identify which attribute you attempted to access and where to go to fix it.
Most of the time, getting this exception indicates that you are probably working with an object that isnât the type you were expecting:
Python
```
```
In the example above, you might be expecting `a_list` to be of type [`list`](https://realpython.com/python-list/), which has a method called [`.append()`](https://realpython.com/python-append/). When you receive the `AttributeError` exception and see that it was raised when you are trying to call `.append()`, that tells you that you probably arenât dealing with the type of object you were expecting.
Often, this happens when you are expecting an object to be returned from a function or method call to be of a specific type, and you end up with an object of type [`None`](https://realpython.com/null-in-python/). In this case, the error message line will read, `AttributeError: 'NoneType' object has no attribute 'append'`.
### `ImportError`
The `ImportError` is raised when something goes wrong with an [import](https://realpython.com/absolute-vs-relative-python-imports/) statement. Youâll get this exception, or its subclass `ModuleNotFoundError`, if the module you are trying to [import](https://realpython.com/python-import/) canât be found or if you try to import something from a module that doesnât exist in the module. The Python documentation defines when this exception is raised:
> Raised when the import statement has troubles trying to load a module. Also raised when the âfrom listâ in `from ... import` has a name that cannot be found. [(Source)](https://docs.python.org/3/library/exceptions.html#ImportError)
Hereâs an example of the `ImportError` and `ModuleNotFoundError` being raised:
Python
```
```
In the example above, you can see that attempting to import a module that doesnât exist, `asdf`, results in the `ModuleNotFoundError`. When attempting to import something that doesnât exist, `asdf`, from a module that does exists, `collections`, this results in an `ImportError`. The error message lines at the bottom of the tracebacks tell you which thing couldnât be imported, `asdf` in both cases.
### `IndexError`
The `IndexError` is raised when you attempt to retrieve an index from a sequence, like a [`list` or a `tuple`](https://realpython.com/python-lists-tuples/), and the index isnât found in the sequence. The Python documentation defines when this exception is raised:
> Raised when a sequence subscript is out of range. [(Source)](https://docs.python.org/3/library/exceptions.html#IndexError)
Hereâs an example that raises the `IndexError`:
Python
```
```
The error message line for an `IndexError` doesnât give you great information. You can see that you have a sequence reference that is `out of range` and what the type of the sequence is, a `list` in this case. That information, combined with the rest of the traceback, is usually enough to help you quickly identify how to fix the issue.
[Remove ads](https://realpython.com/account/join/)
### `KeyError`
Similar to the `IndexError`, the `KeyError` is raised when you attempt to access a key that isnât in the mapping, usually a `dict`. Think of this as the `IndexError` but for [dictionaries](https://realpython.com/python-dicts/). The Python documentation defines when this exception is raised:
> Raised when a mapping (dictionary) key is not found in the set of existing keys. [(Source)](https://docs.python.org/3/library/exceptions.html#KeyError)
Hereâs an example of the `KeyError` being raised:
Python
```
```
The error message line for a `KeyError` gives you the key that could not be found. This isnât much to go on but, combined with the rest of the traceback, is usually enough to fix the issue.
For an in-depth look at `KeyError`, take a look at [Python KeyError Exceptions and How to Handle Them](https://realpython.com/python-keyerror/).
### `NameError`
The `NameError` is raised when you have referenced a variable, module, class, function, or some other name that hasnât been defined in your code. The Python documentation defines when this exception is raised:
> Raised when a local or global name is not found. [(Source)](https://docs.python.org/3/library/exceptions.html#NameError)
In the code below, `greet()` takes a parameter `person`. But in the function itself, that parameter has been misspelled to `persn`:
Python
```
```
The error message line of the `NameError` traceback gives you the name that is missing. In the example above, itâs a misspelled variable or parameter to the function that was passed in.
A `NameError` will also be raised if itâs the parameter that you misspelled:
Python
```
```
Here, it might seem as though youâve done nothing wrong. The last line that was executed and referenced in the traceback looks good. If you find yourself in this situation, then the thing to do is to look through your code for where the `person` variable is used and defined. Here you can quickly see that the parameter name was misspelled.
### `SyntaxError`
The [`SyntaxError`](https://realpython.com/invalid-syntax-python/) is raised when you have incorrect Python syntax in your code. The Python documentation defines when this exception is raised:
> Raised when the parser encounters a syntax error. [(Source)](https://docs.python.org/3/library/exceptions.html#SyntaxError)
Below, the problem is a missing colon that should be at the end of the function definition line. In the Python REPL, this syntax error is raised right away after hitting enter:
Python
```
```
The error message line of the `SyntaxError` only tells you that there was a problem with the syntax of your code. Looking into the lines above gives you the line with the problem and usually a `^` (caret) pointing to the problem spot. Here, the colon is missing from the functionâs `def` statement.
Also, with `SyntaxError` tracebacks, the regular first line `Traceback (most recent call last):` is missing. That is because the `SyntaxError` is raised when Python attempts to parse your code, and the lines arenât actually being executed.
[Remove ads](https://realpython.com/account/join/)
### `TypeError`
The `TypeError` is raised when your code attempts to do something with an object that canât do that thing, such as trying to add a string to an integer or calling `len()` on an object where its length isnât defined. The Python documentation defines when this exception is raised:
> Raised when an operation or function is applied to an object of inappropriate type. [(Source)](https://docs.python.org/3/library/exceptions.html#TypeError)
Following are several examples of the `TypeError` being raised:
Python
```
```
All of the above examples of raising a `TypeError` results in an error message line with different messages. Each of them does a pretty good job of informing you of what is wrong.
The first two examples attempt to add strings and integers together. However, they are subtly different:
- The first is trying to add a `str` to an `int`.
- The second is trying to add an `int` to a `str`.
The error message lines reflect these differences.
The last example attempts to call `len()` on an `int`. The error message line tells you that you canât do that with an `int`.
### `ValueError`
The `ValueError` is raised when the value of the object isnât correct. You can think of this as an `IndexError` that is raised because the value of the index isnât in the range of the sequence, only the `ValueError` is for a more generic case. The Python documentation defines when this exception is raised:
> Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as `IndexError`. [(Source)](https://docs.python.org/3/library/exceptions.html#ValueError)
Here are two examples of `ValueError` being raised:
Python
```
```
The `ValueError` error message line in these examples tells you exactly what the problem is with the values:
1. In the first example, you are trying to unpack too many values. The error message line even tells you that you were expecting to unpack 3 values but got 2 values.
2. In the second example, the problem is that you are getting too many values and not enough variables to unpack them into.
## How Do You Log a Traceback?
Getting an exception and its resulting Python traceback means you need to decide what to do about it. Usually fixing your code is the first step, but sometimes the problem is with unexpected or incorrect input. While itâs good to provide for those situations in your code, sometimes it also makes sense to silence or hide the exception by logging the traceback and doing something else.
Hereâs a more real-world example of code that needs to silence some Python tracebacks. This example uses the [`requests` library](https://2.python-requests.org/en/master/). You can find out more about it in [Pythonâs Requests Library (Guide)](https://realpython.com/python-requests/):
Python
```
```
This code works well. When you run this script, giving it a URL as a [command-line argument](https://realpython.com/python-command-line-arguments/), it will call the URL and then print the HTTP status code and the content from the response. It even works if the response was an HTTP error status:
Shell
```
```
However, sometimes the URL your script is given to retrieve doesnât exist, or the host server is down. In those cases, this script will now raise an uncaught `ConnectionError` exception and print a traceback:
Python Traceback
```
```
The Python traceback here can be very long with many other exceptions being raised and finally resulting in the `ConnectionError` being raised by `requests` itself. If you move up the final exceptions traceback, you can see that the problem all started in our code with line 5 of `urlcaller.py`.
If you wrap the offending line in a [`try` and `except` block](https://realpython.com/python-exceptions/#the-try-and-except-block-handling-exceptions), catching the appropriate exception will allow your script to continue to work with more inputs:
Python
```
```
The code above uses an `else` clause with the `try` and `except` block. If youâre unfamiliar with this feature of Python, then check out the section on the `else` clause in [Python Exceptions: An Introduction](https://realpython.com/python-exceptions/#the-else-clause).
Now when you run the script with a URL that will result in a `ConnectionError` being raised, youâll get printed a `-1` for the status code, and the content `Connection Error`:
Shell
```
```
This works great. However, in most real systems, you donât want to just silence the exception and resulting traceback, but you want to log the traceback. Logging tracebacks allows you to have a better understanding of what goes wrong in your programs.
**Note:** To learn more about Pythonâs logging system, check out [Logging in Python](https://realpython.com/python-logging/).
You can log the traceback in the script by importing the [`logging` package](https://realpython.com/python-logging-source-code/), getting a logger, and calling `.exception()` on that logger in the `except` portion of the `try` and `except` block. Your final script should look something like the following code:
Python
```
```
Now when you run the script for a problematic URL, it will print the expected `-1` and `Connection Error`, but it will also log the traceback:
Python Traceback
```
```
By default, Python will send log messages to standard error (`stderr`). This looks like we havenât suppressed the traceback output at all. However, if you call it again while redirecting the `stderr`, you can see that the logging system is working, and we can save our logs off for later:
Shell
```
```
[Remove ads](https://realpython.com/account/join/)
## Conclusion
The Python traceback contains great information that can help you find what is going wrong in your Python code. These tracebacks can look a little intimidating, but once you break it down to see what itâs trying to show you, they can be super helpful. Going through a few tracebacks line by line will give you a better understanding of the information they contain and help you get the most out of them.
Getting a Python traceback output when you run your code is an opportunity to improve your code. Itâs one way Python tries to help you out.
Now that you know how to read a Python traceback, you can benefit from learning more about some tools and techniques for diagnosing the problems that your traceback output is telling you about. Pythonâs built-in [`traceback` module](https://docs.python.org/3.7/library/traceback.html) can be used to work with and inspect tracebacks. The `traceback` module can be helpful when you need to get more out of the traceback output. It would also be helpful to learn more about some [techniques for debugging](https://realpython.com/search?q=debugging) your Python code and ways to [debug in IDLE](https://realpython.com/python-debug-idle/).
Mark as Completed
Share
Recommended Course
[Getting the Most Out of a Python Traceback](https://realpython.com/courses/python-traceback/) (21m)
đ Python Tricks đ
Get a short & sweet **Python Trick** delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

About **Chad Hansen**
[ ](https://realpython.com/team/chansen/)
Chad is an avid Pythonista and does web development with Django fulltime. Chad lives in Utah with his wife and six kids.
[» More about Chad](https://realpython.com/team/chansen/)
***
*Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:*
[](https://realpython.com/team/asantos/)
[Aldren](https://realpython.com/team/asantos/)
[](https://realpython.com/team/jjablonski/)
[Joanna](https://realpython.com/team/jjablonski/)
[](https://realpython.com/team/mdriscoll/)
[Mike](https://realpython.com/team/mdriscoll/)
Master Real-World Python Skills With Unlimited Access to Real Python

**Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:**
[Level Up Your Python Skills »](https://realpython.com/account/join/?utm_source=rp_article_footer&utm_content=python-traceback)
Master Real-World Python Skills
With Unlimited Access to Real Python

**Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:**
[Level Up Your Python Skills »](https://realpython.com/account/join/?utm_source=rp_article_footer&utm_content=python-traceback)
What Do You Think?
**Rate this article:**
[LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Frealpython.com%2Fpython-traceback%2F)
[Twitter](https://twitter.com/intent/tweet/?text=Interesting%20Python%20article%20on%20%40realpython%3A%20Understanding%20the%20Python%20Traceback&url=https%3A%2F%2Frealpython.com%2Fpython-traceback%2F)
[Bluesky](https://bsky.app/intent/compose?text=Interesting%20Python%20article%20on%20%40realpython.com%3A%20Understanding%20the%20Python%20Traceback%20https%3A%2F%2Frealpython.com%2Fpython-traceback%2F)
[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Frealpython.com%2Fpython-traceback%2F)
[Email](mailto:?subject=Python%20article%20for%20you&body=Understanding%20the%20Python%20Traceback%20on%20Real%20Python%0A%0Ahttps%3A%2F%2Frealpython.com%2Fpython-traceback%2F%0A)
Whatâs your \#1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.
**Commenting Tips:** The most useful comments are those written with the goal of learning from or helping out other students. [Get tips for asking good questions](https://realpython.com/python-beginner-tips/#tip-9-ask-good-questions) and [get answers to common questions in our support portal](https://support.realpython.com/).
***
Looking for a real-time conversation? Visit the [Real Python Community Chat](https://realpython.com/community/) or join the next [âOffice Hoursâ Live Q\&A Session](https://realpython.com/office-hours/). Happy Pythoning\!
Keep Learning
Related Topics: [basics](https://realpython.com/tutorials/basics/) [python](https://realpython.com/tutorials/python/)
Related Courses:
- [Getting the Most Out of a Python Traceback](https://realpython.com/courses/python-traceback/?utm_source=realpython&utm_medium=web&utm_campaign=related-course&utm_content=python-traceback)
Related Tutorials:
- [Beautiful Soup: Build a Web Scraper With Python](https://realpython.com/beautiful-soup-web-scraper-python/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-traceback)
- [Python's raise: Effectively Raising Exceptions in Your Code](https://realpython.com/python-raise-exception/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-traceback)
- [Python Exceptions: An Introduction](https://realpython.com/python-exceptions/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-traceback)
- [Python's with Statement: Manage External Resources Safely](https://realpython.com/python-with-statement/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-traceback)
- [Python Classes: The Power of Object-Oriented Programming](https://realpython.com/python-classes/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-traceback)
## Keep reading Real Python by creating a free account or signing in:
[](https://realpython.com/account/signup/?intent=continue_reading&utm_source=rp&utm_medium=web&utm_campaign=rwn&utm_content=v1&next=%2Fpython-traceback%2F)
[Continue »](https://realpython.com/account/signup/?intent=continue_reading&utm_source=rp&utm_medium=web&utm_campaign=rwn&utm_content=v1&next=%2Fpython-traceback%2F)
Already have an account? [Sign-In](https://realpython.com/account/login/?next=/python-traceback/)
Almost there! Complete this form and click the button below to gain instant access:
Ă

Get the Python Cheat Sheet (Free PDF)
##### Learn Python
- [Start Here](https://realpython.com/start-here/)
- [Learning Resources](https://realpython.com/search)
- [Code Mentor](https://realpython.com/mentor/)
- [Python Reference](https://realpython.com/ref/)
- [Python Cheat Sheet](https://realpython.com/cheatsheets/python/)
- [Support Center](https://support.realpython.com/)
##### Courses & Paths
- [Learning Paths](https://realpython.com/learning-paths/)
- [Quizzes & Exercises](https://realpython.com/quizzes/)
- [Browse Topics](https://realpython.com/tutorials/all/)
- [Live Courses](https://realpython.com/live/)
- [Books](https://realpython.com/books/)
##### Community
- [Podcast](https://realpython.com/podcasts/rpp/)
- [Newsletter](https://realpython.com/newsletter/)
- [Community Chat](https://realpython.com/community/)
- [Office Hours](https://realpython.com/office-hours/)
- [Learner Stories](https://realpython.com/learner-stories/)
##### Membership
- [Plans & Pricing](https://realpython.com/account/join/)
- [Team Plans](https://realpython.com/account/join-team/)
- [For Business](https://realpython.com/account/join-team/inquiry/)
- [For Schools](https://realpython.com/account/join-team/education-inquiry/)
- [Reviews](https://realpython.com/learner-stories/)
##### Company
- [About Us](https://realpython.com/about/)
- [Team](https://realpython.com/team/)
- [Mission & Values](https://realpython.com/mission/)
- [Editorial Guidelines](https://realpython.com/editorial-guidelines/)
- [Sponsorships](https://realpython.com/sponsorships/)
- [Careers](https://realpython.workable.com/)
- [Press Kit](https://realpython.com/media-kit/)
- [Merch](https://realpython.com/merch)
[Privacy Policy](https://realpython.com/privacy-policy/) â
[Terms of Use](https://realpython.com/terms/) â
[Security](https://realpython.com/security/) â
[Contact](https://realpython.com/contact/)
Happy Pythoning\!
© 2012â2026 DevCademy Media Inc. DBA Real Python. All rights reserved.
REALPYTHONâą is a trademark of DevCademy Media Inc.
[](https://realpython.com/)

You've blocked notifications |
| Readable Markdown | Python prints a **traceback** when an exception is raised in your code. The traceback output can be a bit overwhelming if youâre seeing it for the first time or you donât know what itâs telling you. But the Python traceback has a wealth of information that can help you diagnose and fix the reason for the exception being raised in your code. Understanding what information a Python traceback provides is vital to becoming a better Python programmer.
**By the end of this tutorial, youâll be able to:**
- Make sense of the next traceback you see
- Recognize some of the more common tracebacks
- Log a traceback successfully while still handling the exception
## What Is a Python Traceback?
A traceback is a report containing the function calls made in your code at a specific point. Tracebacks are known by many names, including **stack trace**, **stack traceback**, **backtrace**, and maybe others. In Python, the term used is **traceback**.
When your program results in an exception, Python will print the current traceback to help you know what went wrong. Below is an example to illustrate this situation:
Here, `greet()` gets called with the parameter `someone`. However, in `greet()`, that [variable](https://realpython.com/python-variables/) name is not used. Instead, it has been misspelled as `someon` in the [`print()`](https://realpython.com/python-print/) call.
When you run this program, youâll get the following traceback:
This traceback output has all of the information youâll need to diagnose the issue. The final line of the traceback output tells you what type of exception was raised along with some relevant information about that exception. The previous lines of the traceback point out the code that resulted in the exception being raised.
In the above traceback, the exception was a `NameError`, which means that there is a reference to some name (variable, function, class) that hasnât been defined. In this case, the name referenced is `someon`.
The final line in this case has enough information to help you fix the problem. Searching the code for the name `someon`, which is a misspelling, will point you in the right direction. Often, however, your code is a lot more complicated.
## How Do You Read a Python Traceback?
The Python traceback contains a lot of helpful information when youâre trying to determine the reason for an exception being raised in your code. In this section, youâll walk through different tracebacks in order to understand the different bits of information contained in a traceback.
### Python Traceback Overview
There are several sections to every Python traceback that are important. The diagram below highlights the various parts:
[](https://files.realpython.com/media/python_traceback_2.b27a4eb060a8.png)
In Python, itâs best to read the traceback from the bottom up:
1. **Blue box:** The last line of the traceback is the error message line. It contains the exception name that was raised.
2. **Green box:** After the exception name is the error message. This message usually contains helpful information for understanding the reason for the exception being raised.
3. **Yellow box:** Further up the traceback are the various function calls moving from bottom to top, most recent to least recent. These calls are represented by two-line entries for each call. The first line of each call contains information like the file name, line number, and module name, all specifying where the code can be found.
4. **Red underline:** The second line for these calls contains the actual code that was executed.
There are a few differences between traceback output when youâre executing your code in the command-line and running code in the [REPL](https://realpython.com/python-repl/). Below is the same code from the previous section executed in a REPL and the resulting traceback output:
Notice that in place of file names, you get `"<stdin>"`. This makes sense since you typed the code in through standard input. Also, the executed lines of code are not displayed in the traceback.
### Specific Traceback Walkthrough
Going through some specific traceback output will help you better understand and see what information the traceback will give you.
The code below is used in the examples following to illustrate the information a Python traceback gives you:
Here, `who_to_greet()` takes a value, `person`, and either returns it or prompts for a value to return instead.
Then, `greet()` takes a name to be greeted, `someone`, and an optional `greeting` value and calls [`print()`](https://realpython.com/courses/python-print/). `who_to_greet()` is also called with the `someone` value passed in.
Finally, `greet_many()` will iterate over the list of `people` and call `greet()`. If there is an exception raised by calling `greet()`, then a simple backup greeting is printed.
This code doesnât have any bugs that would result in an exception being raised as long as the right input is provided.
If you add a call to `greet()` to the bottom of `greetings.py` and specify a keyword argument that it isnât expecting (for example `greet('Chad', greting='Yo')`), then youâll get the following traceback:
Once again, with a Python traceback, itâs best to work backward, moving up the output. Starting at the final line of the traceback, you can see that the exception was a `TypeError`. The messages that follow the exception type, everything after the colon, give you some great information. It tells you that `greet()` was called with a keyword argument that it didnât expect. The unknown argument name is also given to you: `greting`.
Moving up, you can see the line that resulted in the exception. In this case, itâs the `greet()` call that we added to the bottom of `greetings.py`.
The next line up gives you the path to the file where the code exists, the line number of that file where the code can be found, and which module itâs in. In this case, because our code isnât using any other Python modules, we just see `<module>` here, meaning that this is the file that is being executed.
With a different file and different input, you can see the traceback really pointing you in the right direction to find the issue. If you are following along, remove the buggy `greet()` call from the bottom of `greetings.py` and add the following file to your directory:
Here youâve set up another Python file that is importing your previous module, `greetings.py`, and using `greet()` from it. Hereâs what happens if you now run `example.py`:
The exception raised in this case is a `TypeError` again, but this time the message is a little less helpful. It tells you that somewhere in the code it was expecting to work with a string, but an integer was given.
Moving up, you see the line of code that was executed. Then the file and line number of the code. This time, however, instead of `<module>`, we get the name of the function that was being executed, `greet()`.
Moving up to the next executed line of code, we see our problematic `greet()` call passing in an integer.
Sometimes after an exception is raised, another bit of code catches that exception and also results in an exception. In these situations, Python will output all exception tracebacks in the order in which they were received, once again ending in the most recently raise exceptionâs traceback.
Since this can be a little confusing, hereâs an example. Add a call to `greet_many()` to the bottom of `greetings.py`:
This should result in printing greetings to all three people. However, if you run this code, youâll see an example of the multiple tracebacks being output:
Notice the highlighted line starting with `During handling` in the output above. In between all tracebacks, youâll see this line. Its message is very clear, while your code was trying to handle the previous exception, another exception was raised.
You have seen the previous exception before, when you called `greet()` with an integer. Since we added a `1` to the list of people to greet, we can expect the same result. However, the function `greet_many()` wraps the `greet()` call in a `try` and `except` block. Just in case `greet()` results in an exception being raised, `greet_many()` wants to print a default greeting.
The relevant portion of `greetings.py` is repeated here:
So when `greet()` results in the `TypeError` because of the bad integer input, `greet_many()` handles that exception and attempts to print a simple greeting. Here the code ends up resulting in another, similar, exception. Itâs still attempting to add a string and an integer.
Seeing all of the traceback output can help you see what might be the real cause of an exception. Sometimes when you see the final exception raised, and its resulting traceback, you still canât see whatâs wrong. In those cases, moving up to the previous exceptions usually gives you a better idea of the root cause.
## What Are Some Common Tracebacks in Python?
Knowing how to read a Python traceback when your program raises an exception can be very helpful when youâre programming, but knowing some of the more common tracebacks can also speed up your process.
Here are some common exceptions you might come across, the reasons they get raised and what they mean, and the information you can find in their tracebacks.
### `AttributeError`
The `AttributeError` is raised when you try to access an attribute on an object that doesnât have that attribute defined. The Python documentation defines when this exception is raised:
> Raised when an attribute reference or assignment fails. [(Source)](https://docs.python.org/3/library/exceptions.html#AttributeError)
Hereâs an example of the `AttributeError` being raised:
The error message line for an `AttributeError` tells you that the specific object type, `int` in this case, doesnât have the attribute accessed, `an_attribute` in this case. Seeing the `AttributeError` in the error message line can help you quickly identify which attribute you attempted to access and where to go to fix it.
Most of the time, getting this exception indicates that you are probably working with an object that isnât the type you were expecting:
In the example above, you might be expecting `a_list` to be of type [`list`](https://realpython.com/python-list/), which has a method called [`.append()`](https://realpython.com/python-append/). When you receive the `AttributeError` exception and see that it was raised when you are trying to call `.append()`, that tells you that you probably arenât dealing with the type of object you were expecting.
Often, this happens when you are expecting an object to be returned from a function or method call to be of a specific type, and you end up with an object of type [`None`](https://realpython.com/null-in-python/). In this case, the error message line will read, `AttributeError: 'NoneType' object has no attribute 'append'`.
### `ImportError`
The `ImportError` is raised when something goes wrong with an [import](https://realpython.com/absolute-vs-relative-python-imports/) statement. Youâll get this exception, or its subclass `ModuleNotFoundError`, if the module you are trying to [import](https://realpython.com/python-import/) canât be found or if you try to import something from a module that doesnât exist in the module. The Python documentation defines when this exception is raised:
> Raised when the import statement has troubles trying to load a module. Also raised when the âfrom listâ in `from ... import` has a name that cannot be found. [(Source)](https://docs.python.org/3/library/exceptions.html#ImportError)
Hereâs an example of the `ImportError` and `ModuleNotFoundError` being raised:
In the example above, you can see that attempting to import a module that doesnât exist, `asdf`, results in the `ModuleNotFoundError`. When attempting to import something that doesnât exist, `asdf`, from a module that does exists, `collections`, this results in an `ImportError`. The error message lines at the bottom of the tracebacks tell you which thing couldnât be imported, `asdf` in both cases.
### `IndexError`
The `IndexError` is raised when you attempt to retrieve an index from a sequence, like a [`list` or a `tuple`](https://realpython.com/python-lists-tuples/), and the index isnât found in the sequence. The Python documentation defines when this exception is raised:
> Raised when a sequence subscript is out of range. [(Source)](https://docs.python.org/3/library/exceptions.html#IndexError)
Hereâs an example that raises the `IndexError`:
The error message line for an `IndexError` doesnât give you great information. You can see that you have a sequence reference that is `out of range` and what the type of the sequence is, a `list` in this case. That information, combined with the rest of the traceback, is usually enough to help you quickly identify how to fix the issue.
### `KeyError`
Similar to the `IndexError`, the `KeyError` is raised when you attempt to access a key that isnât in the mapping, usually a `dict`. Think of this as the `IndexError` but for [dictionaries](https://realpython.com/python-dicts/). The Python documentation defines when this exception is raised:
> Raised when a mapping (dictionary) key is not found in the set of existing keys. [(Source)](https://docs.python.org/3/library/exceptions.html#KeyError)
Hereâs an example of the `KeyError` being raised:
The error message line for a `KeyError` gives you the key that could not be found. This isnât much to go on but, combined with the rest of the traceback, is usually enough to fix the issue.
For an in-depth look at `KeyError`, take a look at [Python KeyError Exceptions and How to Handle Them](https://realpython.com/python-keyerror/).
### `NameError`
The `NameError` is raised when you have referenced a variable, module, class, function, or some other name that hasnât been defined in your code. The Python documentation defines when this exception is raised:
> Raised when a local or global name is not found. [(Source)](https://docs.python.org/3/library/exceptions.html#NameError)
In the code below, `greet()` takes a parameter `person`. But in the function itself, that parameter has been misspelled to `persn`:
The error message line of the `NameError` traceback gives you the name that is missing. In the example above, itâs a misspelled variable or parameter to the function that was passed in.
A `NameError` will also be raised if itâs the parameter that you misspelled:
Here, it might seem as though youâve done nothing wrong. The last line that was executed and referenced in the traceback looks good. If you find yourself in this situation, then the thing to do is to look through your code for where the `person` variable is used and defined. Here you can quickly see that the parameter name was misspelled.
### `SyntaxError`
The [`SyntaxError`](https://realpython.com/invalid-syntax-python/) is raised when you have incorrect Python syntax in your code. The Python documentation defines when this exception is raised:
> Raised when the parser encounters a syntax error. [(Source)](https://docs.python.org/3/library/exceptions.html#SyntaxError)
Below, the problem is a missing colon that should be at the end of the function definition line. In the Python REPL, this syntax error is raised right away after hitting enter:
The error message line of the `SyntaxError` only tells you that there was a problem with the syntax of your code. Looking into the lines above gives you the line with the problem and usually a `^` (caret) pointing to the problem spot. Here, the colon is missing from the functionâs `def` statement.
Also, with `SyntaxError` tracebacks, the regular first line `Traceback (most recent call last):` is missing. That is because the `SyntaxError` is raised when Python attempts to parse your code, and the lines arenât actually being executed.
### `TypeError`
The `TypeError` is raised when your code attempts to do something with an object that canât do that thing, such as trying to add a string to an integer or calling `len()` on an object where its length isnât defined. The Python documentation defines when this exception is raised:
> Raised when an operation or function is applied to an object of inappropriate type. [(Source)](https://docs.python.org/3/library/exceptions.html#TypeError)
Following are several examples of the `TypeError` being raised:
All of the above examples of raising a `TypeError` results in an error message line with different messages. Each of them does a pretty good job of informing you of what is wrong.
The first two examples attempt to add strings and integers together. However, they are subtly different:
- The first is trying to add a `str` to an `int`.
- The second is trying to add an `int` to a `str`.
The error message lines reflect these differences.
The last example attempts to call `len()` on an `int`. The error message line tells you that you canât do that with an `int`.
### `ValueError`
The `ValueError` is raised when the value of the object isnât correct. You can think of this as an `IndexError` that is raised because the value of the index isnât in the range of the sequence, only the `ValueError` is for a more generic case. The Python documentation defines when this exception is raised:
> Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as `IndexError`. [(Source)](https://docs.python.org/3/library/exceptions.html#ValueError)
Here are two examples of `ValueError` being raised:
The `ValueError` error message line in these examples tells you exactly what the problem is with the values:
1. In the first example, you are trying to unpack too many values. The error message line even tells you that you were expecting to unpack 3 values but got 2 values.
2. In the second example, the problem is that you are getting too many values and not enough variables to unpack them into.
## How Do You Log a Traceback?
Getting an exception and its resulting Python traceback means you need to decide what to do about it. Usually fixing your code is the first step, but sometimes the problem is with unexpected or incorrect input. While itâs good to provide for those situations in your code, sometimes it also makes sense to silence or hide the exception by logging the traceback and doing something else.
Hereâs a more real-world example of code that needs to silence some Python tracebacks. This example uses the [`requests` library](https://2.python-requests.org/en/master/). You can find out more about it in [Pythonâs Requests Library (Guide)](https://realpython.com/python-requests/):
This code works well. When you run this script, giving it a URL as a [command-line argument](https://realpython.com/python-command-line-arguments/), it will call the URL and then print the HTTP status code and the content from the response. It even works if the response was an HTTP error status:
However, sometimes the URL your script is given to retrieve doesnât exist, or the host server is down. In those cases, this script will now raise an uncaught `ConnectionError` exception and print a traceback:
The Python traceback here can be very long with many other exceptions being raised and finally resulting in the `ConnectionError` being raised by `requests` itself. If you move up the final exceptions traceback, you can see that the problem all started in our code with line 5 of `urlcaller.py`.
If you wrap the offending line in a [`try` and `except` block](https://realpython.com/python-exceptions/#the-try-and-except-block-handling-exceptions), catching the appropriate exception will allow your script to continue to work with more inputs:
The code above uses an `else` clause with the `try` and `except` block. If youâre unfamiliar with this feature of Python, then check out the section on the `else` clause in [Python Exceptions: An Introduction](https://realpython.com/python-exceptions/#the-else-clause).
Now when you run the script with a URL that will result in a `ConnectionError` being raised, youâll get printed a `-1` for the status code, and the content `Connection Error`:
This works great. However, in most real systems, you donât want to just silence the exception and resulting traceback, but you want to log the traceback. Logging tracebacks allows you to have a better understanding of what goes wrong in your programs.
You can log the traceback in the script by importing the [`logging` package](https://realpython.com/python-logging-source-code/), getting a logger, and calling `.exception()` on that logger in the `except` portion of the `try` and `except` block. Your final script should look something like the following code:
Now when you run the script for a problematic URL, it will print the expected `-1` and `Connection Error`, but it will also log the traceback:
By default, Python will send log messages to standard error (`stderr`). This looks like we havenât suppressed the traceback output at all. However, if you call it again while redirecting the `stderr`, you can see that the logging system is working, and we can save our logs off for later:
## Conclusion
The Python traceback contains great information that can help you find what is going wrong in your Python code. These tracebacks can look a little intimidating, but once you break it down to see what itâs trying to show you, they can be super helpful. Going through a few tracebacks line by line will give you a better understanding of the information they contain and help you get the most out of them.
Getting a Python traceback output when you run your code is an opportunity to improve your code. Itâs one way Python tries to help you out.
Now that you know how to read a Python traceback, you can benefit from learning more about some tools and techniques for diagnosing the problems that your traceback output is telling you about. Pythonâs built-in [`traceback` module](https://docs.python.org/3.7/library/traceback.html) can be used to work with and inspect tracebacks. The `traceback` module can be helpful when you need to get more out of the traceback output. It would also be helpful to learn more about some [techniques for debugging](https://realpython.com/search?q=debugging) your Python code and ways to [debug in IDLE](https://realpython.com/python-debug-idle/). |
| Shard | 71 (laksa) |
| Root Hash | 13351397557425671 |
| Unparsed URL | com,realpython!/python-traceback/ s443 |