Back to Scaling Python Applications guides

15 Common Errors in Python and How to Fix Them

Stanley Ulili
Updated on December 8, 2023

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.

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.

1. SyntaxError

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:

  • Unclosed strings
  • Indentation issues
  • Misusing the assignment operator (=)
  • Misspelling Python keywords
  • Missing brackets, parentheses, or braces
  • Using newer Python syntax on an old version of Python.

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:

Output
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:

  • File name
  • Line number
  • Location indicated by the caret (^)
  • Error message, which can offer insights into the nature of the problem.
  • The question added at the end of the error message provides valuable context.

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:

Screenshot of Pylance highlighting an error

2. IndentationError

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:

Output
  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:

Screenshot of a linter identifying indentation errors

3. NameError

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:

Screenshot of Pylance detecting a `NameError` in the code`

4. ValueError

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:

Output
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.

5. UnboundLocalError

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:

Output
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:

  • A local variable in a function having the same name as a global variable, known as shadowing a global variable.
  • Using the del operator on a local variable that you referenced later.

To fix UnboundLocalError:

  • Assign values to local variables before referencing them.
  • If caused by shadowing a global variable, use a name different from the global variable.
  • Avoid using the del operator on variables you will reference later.

6. TypeError

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:

Output
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:

  • Only iterate through iterable sequences.
  • Use arguments that match the expected types in built-in functions.
  • Supply the correct number of arguments when calling a function.
  • Compare or convert to a common type when dealing with different data types.

7. UnicodeError

A UnicodeError exception is raised when Python encounters encoding or decoding issues. The reasons for this error include:

  • Conflicts due to mixed encoding in the text.
  • Incorrect byte order marks (BOM) leading to decoding errors.
  • Use of unsupported or mismatched encoding schemes.
  • Conflicts arising from different Unicode standards.
  • Problems with surrogate pairs in UTF-16.
  • Corrupted or incomplete byte sequences.

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'))
Output
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.

8. ZeroDivisionError

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:

Output
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.

9. FileNotFoundError

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:

Output
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.

10. ModuleNotFoundError

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:

Output
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.

11. MemoryError

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:

Output
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.

12. PermissionError

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:

Output
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.

13. IndexError

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:

Output
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])

14. KeyError

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:

Output
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.")

15. AttributeError

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:

Output
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:

Output
main.py:2: error: "list[int]" has no attribute "lower"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

Dealing with Python errors in production

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.

search-filter.png

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.

error-alert.png

Sign up for a free account, and see how easy error monitoring can be.

Final thoughts

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!

Author's avatar
Article by
Stanley Ulili
Stanley Ulili is a technical educator at Better Stack based in Malawi. He specializes in backend development and has freelanced for platforms like DigitalOcean, LogRocket, and AppSignal. Stanley is passionate about making complex topics accessible to developers.
Got an article suggestion? Let us know
Next article
A Comprehensive Guide to Logging in Python
Python provides a built-in logging module in its standard library that provides comprehensive logging capabilities for Python programs
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Make your mark

Join the writer's program

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 us
Writer of the month
Marin Bezhanov
Marin is a software engineer and architect with a broad range of experience working...
Build on top of Better Stack

Write 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.com

or submit a pull request and help us build better products for everyone.

See the full list of amazing projects on github