Side note: Get a Python logs dashboard
Save hours of sifting through Python logs. Centralize with Better Stack and start visualizing your log data in minutes.
See the Python demo dashboard live.
When building Python applications, it's a given that you'll run into errors. Learning to identify and fix these errors is essential for effective debugging, time-saving, and more importantly, avoiding such errors in the future.
This article presents a collection of 15 frequent Python errors and their solutions. Although this list doesn't encompass all possible Python errors, it aims to acquaint you with common problems, equipping you to deal with them as they arise.
Save hours of sifting through Python logs. Centralize with Better Stack and start visualizing your log data in minutes.
See the Python demo dashboard live.
SyntaxError
is a common error that occurs when the Python interpreter parses
your code and finds incorrect code that does not conform to the syntax rules.
Some common causes of SyntaxError
include:
=
)When this error occurs, a traceback is produced to help you determine where the problem is. Take the following example:
employees = {"pam" 30,
"jim": 28}
for name, age in employees.items():
print(f"{name.capitalize()} is {age} years old.")
On line 1, the syntax is invalid because the dictionary's first property lacks a
colon (:
) to separate the property "pam"
and the value 30
. When the code
is executed, the following traceback is produced:
File "/home/stanley/code_samples/main.py", line 1
employees = {"pam" 30,
^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
The traceback message has multiple carets (^
) showing where the invalid syntax
was encountered. While it sometimes might not pinpoint the exact location, it
will usually hint at the issue's probable location.
To address this issue, carefully consider the following information in the traceback:
To catch syntax errors before you execute the code, configure a linter within your code editor, such as Pylint, Flake8 to statically analyze the code.
In the screenshot below, Pylance is used to highlights problematic areas with a red underline in VS Code:
The IndentationError
occurs in Python when there's an indentation issue in
your code. Common causes include mixing tabs with spaces, incorrect spacing,
incorrectly nested blocks, or whitespace at the beginning of a statement or
file.
Consider the following example:
if True:
print("Incorrectly indented")
This triggers a Python traceback similar to:
File "/home/stanley/code_samples/main.py", line 2
print("Missing colon")
^
IndentationError: expected an indented block after 'if' statement on line 1
To address and prevent this issue, use an editor or IDE configured with formatters like Black, which auto-formats your code as you write. The previously mentioned Pylance linter can also help you identify indentation errors:
Python raises a NameError
if you attempt to use an identifier that hasn't been
defined or might be out of scope. Other potential causes of a NameError
include referencing a variable before its assignment or misspelling an
identifier:
print(name)
In this example, the name
variable is not defined but is being accessed. As a
result, Python throws an exception:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
print(name)
NameError: name 'name' is not defined
To fix this problem, ensure that the variable or function name you want to use has been defined. Check for spelling errors and ensure that the variable you want to use is within the scope where it is being accessed.
Again, setting up a linter in your editor will help you catch such problems error early in the development process:
The ValueError
exception indicates that a function received an argument of the
correct data type; however, the value itself is invalid. For example, the
int()
method accepts only integer string like "42"
, and passing something
like "forty-two"
will yield a ValueError
:
num = int("forty-two")
This leads to Python throwing an exception like this:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
num = int("forty-two")
ValueError: invalid literal for int() with base 10: 'forty-two'
Another common cause is passing an empty iterable to the max()
or min()
built-in functions, e.g., max([])
.
To resolve this issue, provide the correct data type and value as an argument to the built-in functions. Check the documentation for the specific function you're using to ensure compliance with expected input formats.
If applicable, consider using try-except
blocks, to gracefully manage
potential user input errors and prevent ValueError
occurrences that bring down
your entire program.
The UnboundLocalError
often occurs when you use a local variable within a
function or method before assigning a value to it. For example, referencing the
name
variable before setting its value:
def display_name():
print(name)
name = "John"
display_name()
You will see an exception resembling this:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 5, in <module>
display_name()
File "/home/stanley/code_samples/main.py", line 2, in display_name
print(name)
UnboundLocalError: local variable 'name' referenced before assignment
Other common causes for this error include:
del
operator on a local variable that you referenced later.To fix UnboundLocalError
:
del
operator on variables you will reference later.A TypeError
exception in Python indicates that you are performing an operation
that is not supported or appropriate for the object data type. For example,
trying to divide a string with an integer:
print("hello" / 3)
This produces an exception that looks like the following:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
print("hello" / 3)
TypeError: unsupported operand type(s) for /: 'str' and 'int'
This exception can also occur in situations like trying to loop over a
non-iterable (such as a float or integer) or using incorrect argument types for
built-in methods (like passing an integer to len(),
which expects an
iterable). Furthermore, calling a function with fewer arguments than required or
comparing different data types can also lead to a TypeError
.
To avoid these errors, ensure the following:
A UnicodeError
exception is raised when Python encounters encoding or decoding
issues. The reasons for this error include:
Consider this example where decoding a Unicode string with ASCII results in an error:
unicode_str = "\u1234\u5678\u90AB"
decoded_str = unicode_str.encode('utf-8')
print(decoded_str.decode('ascii'))
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 3, in <module>
print(decoded_str.decode('ascii'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe1 in position 0: ordinal not in range(128)
To mitigate such issues, use a reliable encoding like UTF-8 and ensure strings are valid Unicode. Implementing error-handling strategies like try-except blocks can also help manage encoding errors. Additionally, pay attention to Byte Order Marks when working with files or data streams, and inspect the encoding and character standards of external data sources.
Python raises the ZeroDivisionError
exception when you attempt to divide a
number by zero:
result = 5 / 0
print(result)
Python will throw the following exception:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
result = 5 / 0
ZeroDivisionError: division by zero
To fix this, avoid dividing numbers by zero. A strategy you can use is to check if the divisor is zero:
numerator = 5
denominator = 0
if denominator != 0:
result = numerator / denominator
else:
print("Division by zero avoided.")
This way, you can prevent the ZeroDivisionError
by ensuring that the
denominator is not zero before performing the division.
Python throws this exception when it attempts to perform file-related operations, such as reading, writing, or deleting a file that does not exist in the given location:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
with open('file_does_not_exist.txt', 'r') as file:
FileNotFoundError: [Errno 2] No such file or directory: 'file_does_not_exist.txt'
To fix this, ensure that the file exists at the given location. Also, double-check the file path, file extension, and take into account relative or absolute paths to the file.
Often, the program might receive incorrect file paths from users, which is
beyond your control. A good solution is to use a try-except
block to handle
the FileNotFoundError
so that the program doesn't crash:
file_path = 'file_does_not_exist.txt'
try:
with open(file_path, 'r') as file:
content = file.read()
# Additional file processing code can go here
except FileNotFoundError:
print(f"The file '{file_path}' does not exist.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
This way, you can gracefully handle the absence of a file and prevent the program from crashing.
Python raises the ModuleNotFoundError
when it can't import a module. This
issue may arise if the module isn't installed on your system or in the virtual
environment. Sometimes, the error could be due to an incorrect module path or
name. Additionally, this error occurs when importing from a package that lacks a
__init__.py
file.
An example of this error's traceback is:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
import arrow
ModuleNotFoundError: No module named 'arrow'
To resolve this, first check if the module is installed, using pip
for
third-party modules. Secondly, verify the accuracy of the module name and file
path, as errors here can lead to this issue. Lastly, ensure that Python packages
contain a __init__.py
file, necessary for Python to recognize them as valid
packages.
A MemoryError
in Python occurs when the system runs out of memory. This is
often caused by memory leaks where memory is continuously consumed without being
released, or by loading large files entirely instead of in smaller chunks.
For example, this code attempting to create a list with over a billion elements:
large_list = [0] * (10**9) # Attempting to create a list with more than a billion elements
leads to a MemoryError
:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
large_list = [0] * (10**9) # Attempting to create a list with more than a billion elements
MemoryError
To handle this, use memory profiling tools like Scalene to pinpoint the memory-intensive parts of your program.
For Python servers, an interim fix could be setting up an auto-restart mechanism that activates when memory usage crosses a certain limit. This approach can temporarily alleviate memory leaks by periodically freeing up memory.
For large file operations, read files in smaller chunks. If the file is line-based, iterate over discrete lines:
with open("large_file.txt") as file:
for line in file:
print(line)
For single-line large files, consider using a Python generator. This method is detailed in this Stack Overflow post on processing large text files.
Python raises a PermissionError
when it tries to execute an operation without
the required privileges, such as accessing or modifying restricted files or
directories. This error can also occur if a file is currently in use by another
program.
For example, trying to create a directory in a protected area like /etc
:
import os
os.mkdir("/etc/new_directory")
results in the following traceback:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 3, in <module>
os.mkdir("/etc/new_directory")
PermissionError: [Errno 13] Permission denied: '/etc/new_directory'
To address a PermissionError
, consider running your script with elevated
privileges using sudo, but be cautious as it can be risky.
Other solutions include modifying file or directory permissions with
os.chmod()
, adjusting
ACLs using
setfacl
, or moving the file/directory to a location with write permissions
using shutil.move()
. The right solution here depends on your specific needs
and security considerations.
An IndexError
is often encountered when you attempt to access an index in a
sequence, such as a list, tuple, or string, and it is outside the valid range.
For instance, trying to access index 4 in a list with only three elements:
numbers = [10, 20, 30]
numbers[4]
results in the following exception:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 2, in <module>
numbers[4]
~~~~~~~^^^
IndexError: list index out of range
To prevent IndexError, ensure that the index you're accessing falls within the sequence's valid range. This can be checked by comparing the index with the sequence's length, obtainable using the len() method.
numbers = [10, 20, 30]
# Ensure the index is within the range of the list
index = 4
if index < len(numbers):
print(numbers[index])
A KeyError
in Python is raised when an attempt is made to access a dictionary
value using a key that doesn't exist. This error can occur if the key is
missing, if there's a typographical error, or if the dictionary is empty:
my_dict = {'name': 'John', 'age': 25}
print(my_dict['location']) # the 'location' key does not exist
The error message produced looks like this:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 2, in <module>
print(my_dict['location']) # the 'location' key does not exist
~~~~~~~^^^^^^^^^^^^
KeyError: 'location'
To avoid a KeyError
, verify the presence of the key in the dictionary and
ensure there are no typos. Alternatively, use the dict.get()
method, which can
return a default value if the key is not found:
my_dict = {'name': 'John', 'age': 25}
print(my_dict.get('location', None))
For a more robust approach, use get()
and handle the result accordingly:
my_dict = {'name': 'John', 'age': 25}
location = my_dict.get('location')
if location is not None:
print("Location:", location)
else:
print("Location key not found in the dictionary.")
An AttributeError in Python is raised when there's an attempt to access or utilize an attribute that an object or class doesn't possess. For instance, since a list lacks the lower() method:
my_list = [1, 2, 3]
print(my_list.lower())
This attempt results in the following error message:
Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 2, in <module>
print(my_list.lower())
^^^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'lower'
To prevent this error, ensure that you're using attributes and methods that are actually available for the given object. This can be confirmed by consulting the object's documentation. Additionally, verify the correct spelling of the attribute names.
You can also use tools like Mypy for static analysis to detect such issues early. Mypy would indicate a problem in the above code as follows:
main.py:2: error: "list[int]" has no attribute "lower" [attr-defined]
Found 1 error in 1 file (checked 1 source file)
While we've explored common Python errors and their solutions, it's important to recognize that errors are inevitable in any sufficiently complex programs. To effectively troubleshoot errors in a production environment, you should adopt a comprehensive logging strategy to understand the behavior of your application.
This practice is crucial for diagnosing issues after they occur. Python offers various logging frameworks that can be seamlessly integrated into your application. Here's a basic example of setting up logging in Python:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
try:
1 / 0
except ZeroDivisionError as e:
logger.exception(e)
Learn more: A Comprehensive Guide to Logging in Python
Once you've started generating logs, aggregating them into a central repository simplifies the debugging process by notifying you when such issues occur and providing an interface to search and visualize all your data.
Better Stack offers a powerful log management solution that not only stores logs but also provides advanced search, monitoring, and alerting capabilities to help you mitigate errors much faster.
Sign up for a free account, and see how easy error monitoring can be.
Understanding the common causes of Python errors and how to address them is crucial for efficient problem-solving. In this article, we explored 15 common errors in Python and discussed various strategies to resolve them.
For further exploration, the Python documentation offers detailed information on exceptions and custom exception creation.
You should also check out our logging guides for further guidance on how to create a comprehensive logging strategy for your Python applications.
Thanks for reading, and happy coding!
Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.
Write for usWrite a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.
community@betterstack.comor submit a pull request and help us build better products for everyone.
See the full list of amazing projects on github