New error messages in Python 3.14
Updated
Python 3.14 replaced many plain "invalid syntax" errors with messages that name the mistake, and made two common TypeErrors say what you were doing. Each example below ran on 3.13 and on 3.14.
Misspelt keywords
A word that is close to a Python keyword gets a suggestion. The check covers the common cases; some misspellings still give a plain "invalid syntax".
whille True:
pass File "/home/me/project/main.py", line 1
whille True:
^^^^^^
SyntaxError: invalid syntax. Did you mean 'while'?| Python | Prints |
|---|---|
| 3.13 | SyntaxError: invalid syntax |
| 3.14 | SyntaxError: invalid syntax. Did you mean 'while'? |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
elif after else
answer = 42
if answer > 50:
print("big")
else:
print("small")
elif answer == 42:
print("exactly") File "/home/me/project/main.py", line 6
elif answer == 42:
^^^^
SyntaxError: 'elif' block follows an 'else' block| Python | Prints |
|---|---|
| 3.13 | SyntaxError: invalid syntax |
| 3.14 | SyntaxError: 'elif' block follows an 'else' block |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
A statement where an expression belongs
In a conditional expression, pass, break or continue after else or before if now gets a message that says an expression is needed there.
x = 1 if True else pass File "/home/me/project/main.py", line 1
x = 1 if True else pass
^^^^
SyntaxError: expected expression after 'else', but statement is given| Python | Prints |
|---|---|
| 3.13 | SyntaxError: invalid syntax |
| 3.14 | SyntaxError: expected expression after 'else', but statement is given |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
A quote that closes a string too early
title = "The "Big" Book" File "/home/me/project/main.py", line 1
title = "The "Big" Book"
^^^
SyntaxError: invalid syntax. Is this intended to be part of the string?| Python | Prints |
|---|---|
| 3.13 | SyntaxError: invalid syntax |
| 3.14 | SyntaxError: invalid syntax. Is this intended to be part of the string? |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
Prefixes that cannot be combined
data = ub"abc" File "/home/me/project/main.py", line 1
data = ub"abc"
^^
SyntaxError: 'u' and 'b' prefixes are incompatible| Python | Prints |
|---|---|
| 3.13 | SyntaxError: invalid syntax |
| 3.14 | SyntaxError: 'u' and 'b' prefixes are incompatible |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
An attribute after as
import … as, from … import … as, except … as and case … as with a target such as a.b now get a message about the target.
import os as os.path File "/home/me/project/main.py", line 1
import os as os.path
^^^^^^^
SyntaxError: cannot use attribute as import target| Python | Prints |
|---|---|
| 3.13 | SyntaxError: invalid syntax |
| 3.14 | SyntaxError: cannot use attribute as import target |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
Unhashable dict keys and set items
The message says whether the value was used as a dict key or a set element, and keeps the old wording in brackets.
counts = {}
counts[["a", "b"]] = 1Traceback (most recent call last):
File "/home/me/project/main.py", line 2, in <module>
counts[["a", "b"]] = 1
~~~~~~^^^^^^^^^^^^
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')| Python | Prints |
|---|---|
| 3.13 | TypeError: unhashable type: 'list' |
| 3.14 | TypeError: cannot use 'list' as a dict key (unhashable type: 'list') |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
with on an async context manager
Entering an asynchronous context manager with with, or a synchronous one with async with, now says which one you meant.
class Lock:
async def __aenter__(self):
return self
async def __aexit__(self, *exc):
return False
with Lock():
passTraceback (most recent call last):
File "/home/me/project/main.py", line 8, in <module>
with Lock():
~~~~^^
TypeError: 'Lock' object does not support the context manager protocol (missed __exit__ method) but it supports the asynchronous context manager protocol. Did you mean to use 'async with'?| Python | Prints |
|---|---|
| 3.13 | TypeError: 'Lock' object does not support the context manager protocol |
| 3.14 | TypeError: 'Lock' object does not support the context manager protocol (missed __exit__ method) but it supports the asynchronous context manager protocol. Did you mean to use 'async with'? |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
The count in unpacking errors
Not in the What's New list, but visible in the runs: when the right side is a tuple, a list or a dict, 3.14 adds how many values it got.
x, y = (3, 4, 5)Traceback (most recent call last):
File "/home/me/project/main.py", line 1, in <module>
x, y = (3, 4, 5)
^^^^
ValueError: too many values to unpack (expected 2, got 3)| Python | Prints |
|---|---|
| 3.13 | ValueError: too many values to unpack (expected 2) |
| 3.14 | ValueError: too many values to unpack (expected 2, got 3) |
Run on CPython 3.13.17 and 3.14.9, on October 25, 2026.
Sources
- What's New in Python 3.14: improved error messages, Python documentation
Read on October 25, 2026.