Errors Everywhere#
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "numpy",
# "matplotlib",
# ]
# ///
A Short Overview of Error Messages in Python#
In this notebook, we explore common Python errors through short, live-coded examples. The goal is not just to recognise these errors, but to understand how Python helps you debug them.
There are two key ideas to keep in mind:
Error type tells you what went wrong (e.g.
SyntaxError
,TypeError
,IndexError
).Traceback tells you where it went wrong — it points to the exact line and function where the problem occurred. Understanding these two aspects will help you fix bugs faster and read error messages more confidently. Let’s get started.
Error Types and Tracebacks#
When Python encounters an error, it raises an exception.
_IncompleteInputError#
Close parenthesis are missing.
print('hello'
Cell In[2], line 1
print('hello'
^
SyntaxError: incomplete input
SyntaxError#
Unterminated string. The closing quote is missing.
print('error)
Cell In[44], line 1
print('error)
^
SyntaxError: unterminated string literal (detected at line 1)
SyntaxError#
The first line of the function definition requires a colon at the end.
def cool_function(a, b)
return a + b
Cell In[45], line 1
def cool_function(a, b)
^
SyntaxError: expected ':'
IndentationError#
The return
statement must be indented.
def cool_function_final(a, b):
return a + b
Cell In[46], line 2
return a + b
^
IndentationError: expected an indented block after function definition on line 1
TypeError#
Can’t add a string and an integer without conversion.
a = 2
b = '2'
a + b
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[48], line 3
1 a = 2
2 b = '2'
----> 3 a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
ValueError#
‘one’ can’t be converted to an integer.
int("one")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[50], line 1
----> 1 int("one")
ValueError: invalid literal for int() with base 10: 'one'
IndexError#
We’re trying to access a list index that doesn’t exist.
my_list = [1, 2, 3]
print(my_list[10])
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[51], line 2
1 my_list = [1, 2, 3]
----> 2 print(my_list[10])
IndexError: list index out of range
KeyError#
The dictionary key ‘b’ doesn’t exist.
my_dict = {"a": 1}
print(my_dict["b"])
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[52], line 2
1 my_dict = {"a": 1}
----> 2 print(my_dict["b"])
KeyError: 'b'
FileNotFoundError#
Trying to load a file that probably doesn’t exist.
import numpy as np
x = np.load('data.npy')
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
Cell In[53], line 2
1 import numpy as np
----> 2 x = np.load('data.npy')
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/numpy/lib/_npyio_impl.py:454, in load(file, mmap_mode, allow_pickle, fix_imports, encoding, max_header_size)
452 own_fid = False
453 else:
--> 454 fid = stack.enter_context(open(os.fspath(file), "rb"))
455 own_fid = True
457 # Code to distinguish from NumPy binary files and pickles.
FileNotFoundError: [Errno 2] No such file or directory: 'data.npy'
Tracebacks - localising the error#
Understanding where in the code the error was raised is as important as understanding what the error is. Every error message will tell you the exact line of code that raised the error. Here explore how to read them.
ZeroDivisionError#
Division by zero is undefined. Traceback shows which line caused it; line 2. Note that line 3 would raise the same error, but we only see the error caused by line 2 since the code execution is stopped when the first error is encountered.
x = 10 * 0
y = 10 / 0
z = 10 / 0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[4], line 2
1 x = 10 * 0
----> 2 y = 10 / 0
3 z = 10 / 0
ZeroDivisionError: division by zero
No error (yet)#
Function is defined, but contains a reference to an undefined variable.
def another_function(x, y):
return undeclared_variable
NameError#
Calling the function reveals the undefined variable. Traceback shows that the error was caused by calling the another_function
, where in the notebook that function lives (the number in square brackets), and which line in the function caused the error.
another_function(1, 2)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[56], line 1
----> 1 another_function(1, 2)
Cell In[55], line 2, in another_function(x, y)
1 def another_function(x, y):
----> 2 return undeclared_variable
NameError: name 'undeclared_variable' is not defined
NameError#
Typo in variable name inside nested functions. Traceback shows nested calls and leads us through this more complicated code to the error.
import matplotlib.pyplot as plt
import numpy as np
def draw_branch(x, y, angle, length, depth, lines):
if depth == 0:
return
x2 = x + np.cos(angle) * length
y2 = y + np.sin(angle) * length
lines.append(((x, x2), (y, yii)))
new_length = length * 0.7
draw_branch(x2, y2, angle + np.pi / 6, new_length, depth - 1, lines)
draw_branch(x2, y2, angle - np.pi / 4, new_length, depth - 1, lines)
def plot_tree():
lines = []
draw_branch(0, 0, np.pi / 2, 1, 6, lines)
for (x, y) in lines:
plt.plot(x, y, 'k-', lw=1)
plt.axis('off')
plt.gca().set_aspect('equal')
plt.show()
plot_tree()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[57], line 23
20 plt.gca().set_aspect('equal')
21 plt.show()
---> 23 plot_tree()
Cell In[57], line 16, in plot_tree()
14 def plot_tree():
15 lines = []
---> 16 draw_branch(0, 0, np.pi / 2, 1, 6, lines)
17 for (x, y) in lines:
18 plt.plot(x, y, 'k-', lw=1)
Cell In[57], line 9, in draw_branch(x, y, angle, length, depth, lines)
7 x2 = x + np.cos(angle) * length
8 y2 = y + np.sin(angle) * length
----> 9 lines.append(((x, x2), (y, yii)))
10 new_length = length * 0.7
11 draw_branch(x2, y2, angle + np.pi / 6, new_length, depth - 1, lines)
NameError: name 'yii' is not defined
ValueError#
Invalid colormap. Error message is very long and not very helpful, but the developers added more details and suggests valid options.
import matplotlib.pyplot as plt
plt.imshow(np.zeros((10, 10)), cmap='error')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[41], line 2
1 import matplotlib.pyplot as plt
----> 2 plt.imshow(np.zeros((10, 10)), cmap='error')
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/pyplot.py:3601, in imshow(X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, colorizer, origin, extent, interpolation_stage, filternorm, filterrad, resample, url, data, **kwargs)
3579 @_copy_docstring_and_deprecators(Axes.imshow)
3580 def imshow(
3581 X: ArrayLike | PIL.Image.Image,
(...) 3599 **kwargs,
3600 ) -> AxesImage:
-> 3601 __ret = gca().imshow(
3602 X,
3603 cmap=cmap,
3604 norm=norm,
3605 aspect=aspect,
3606 interpolation=interpolation,
3607 alpha=alpha,
3608 vmin=vmin,
3609 vmax=vmax,
3610 colorizer=colorizer,
3611 origin=origin,
3612 extent=extent,
3613 interpolation_stage=interpolation_stage,
3614 filternorm=filternorm,
3615 filterrad=filterrad,
3616 resample=resample,
3617 url=url,
3618 **({"data": data} if data is not None else {}),
3619 **kwargs,
3620 )
3621 sci(__ret)
3622 return __ret
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/__init__.py:1521, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
1518 @functools.wraps(func)
1519 def inner(ax, *args, data=None, **kwargs):
1520 if data is None:
-> 1521 return func(
1522 ax,
1523 *map(cbook.sanitize_sequence, args),
1524 **{k: cbook.sanitize_sequence(v) for k, v in kwargs.items()})
1526 bound = new_sig.bind(ax, *args, **kwargs)
1527 auto_label = (bound.arguments.get(label_namer)
1528 or bound.kwargs.get(label_namer))
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/axes/_axes.py:5965, in Axes.imshow(self, X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, colorizer, origin, extent, interpolation_stage, filternorm, filterrad, resample, url, **kwargs)
5747 @_preprocess_data()
5748 @_docstring.interpd
5749 def imshow(self, X, cmap=None, norm=None, *, aspect=None,
(...) 5752 interpolation_stage=None, filternorm=True, filterrad=4.0,
5753 resample=None, url=None, **kwargs):
5754 """
5755 Display data as an image, i.e., on a 2D regular raster.
5756
(...) 5963 (unassociated) alpha representation.
5964 """
-> 5965 im = mimage.AxesImage(self, cmap=cmap, norm=norm, colorizer=colorizer,
5966 interpolation=interpolation, origin=origin,
5967 extent=extent, filternorm=filternorm,
5968 filterrad=filterrad, resample=resample,
5969 interpolation_stage=interpolation_stage,
5970 **kwargs)
5972 if aspect is None and not (
5973 im.is_transform_set()
5974 and not im.get_transform().contains_branch(self.transData)):
5975 aspect = mpl.rcParams['image.aspect']
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/image.py:884, in AxesImage.__init__(self, ax, cmap, norm, colorizer, interpolation, origin, extent, filternorm, filterrad, resample, interpolation_stage, **kwargs)
867 def __init__(self, ax,
868 *,
869 cmap=None,
(...) 879 **kwargs
880 ):
882 self._extent = extent
--> 884 super().__init__(
885 ax,
886 cmap=cmap,
887 norm=norm,
888 colorizer=colorizer,
889 interpolation=interpolation,
890 origin=origin,
891 filternorm=filternorm,
892 filterrad=filterrad,
893 resample=resample,
894 interpolation_stage=interpolation_stage,
895 **kwargs
896 )
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/image.py:263, in _ImageBase.__init__(self, ax, cmap, norm, colorizer, interpolation, origin, filternorm, filterrad, resample, interpolation_stage, **kwargs)
250 def __init__(self, ax,
251 cmap=None,
252 norm=None,
(...) 261 **kwargs
262 ):
--> 263 super().__init__(self._get_colorizer(cmap, norm, colorizer))
264 if origin is None:
265 origin = mpl.rcParams['image.origin']
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/colorizer.py:610, in _ScalarMappable._get_colorizer(cmap, norm, colorizer)
606 _ScalarMappable._check_exclusionary_keywords(
607 Colorizer, cmap=cmap, norm=norm
608 )
609 return colorizer
--> 610 return Colorizer(cmap, norm)
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/colorizer.py:56, in Colorizer.__init__(self, cmap, norm)
53 def __init__(self, cmap=None, norm=None):
55 self._cmap = None
---> 56 self._set_cmap(cmap)
58 self._id_norm = None
59 self._norm = None
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/colorizer.py:237, in Colorizer._set_cmap(self, cmap)
235 from matplotlib import cm
236 in_init = self._cmap is None
--> 237 self._cmap = cm._ensure_cmap(cmap)
238 if not in_init:
239 self.changed()
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/cm.py:309, in _ensure_cmap(cmap)
306 # use check_in_list to ensure type stability of the exception raised by
307 # the internal usage of this (ValueError vs KeyError)
308 if cmap_name not in _colormaps:
--> 309 _api.check_in_list(sorted(_colormaps), cmap=cmap_name)
310 return mpl.colormaps[cmap_name]
File ~/.cache/uv/environments-v2/juv-tmp-q5418f1c-660e5b8f23e19f4b/lib/python3.13/site-packages/matplotlib/_api/__init__.py:130, in check_in_list(values, _print_supported_values, **kwargs)
128 if _print_supported_values:
129 msg += f"; supported values are {', '.join(map(repr, values))}"
--> 130 raise ValueError(msg)
ValueError: 'error' is not a valid value for cmap; supported values are 'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Grays', 'Grays_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'berlin', 'berlin_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_grey', 'gist_grey_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gist_yerg', 'gist_yerg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'grey', 'grey_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'managua', 'managua_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'vanimo', 'vanimo_r', 'viridis', 'viridis_r', 'winter', 'winter_r'

Wrapping Up#
Errors are not your enemy—they’re your most helpful feedback while programming. By learning to read both the type of error (what went wrong) and the traceback (where it went wrong), you gain a powerful tool for debugging and understanding your code. As you write more complex programs, especially with functions and libraries, tracebacks will guide you through layers of execution to pinpoint the real issue.
Remember: every programmer sees errors. Skilled programmers just read them better.