Skip to content

Fix: Python SyntaxError: invalid syntax

FixDevs ·

Quick Answer

How to fix Python SyntaxError invalid syntax caused by missing colons, parentheses, wrong operators, Python 2 vs 3 syntax, f-strings, and walrus operator issues.

The Error

You run a Python script and get:

  File "app.py", line 5
    if x == 10
             ^
SyntaxError: invalid syntax

Or variations:

SyntaxError: invalid syntax (line 12)
SyntaxError: invalid syntax. Perhaps you forgot a comma?
SyntaxError: f-string: expecting '}'

Python’s parser could not understand your code. The ^ caret points to approximately where the parser gave up, but the actual mistake is often on the line before or a few characters earlier.

Why This Happens

Python’s parser reads your code token by token. When it encounters something unexpected — a missing colon, an unmatched parenthesis, a keyword used as a variable name — it stops and reports SyntaxError.

The error location is where the parser gave up, not necessarily where the mistake is. A missing closing parenthesis on line 5 might cause a SyntaxError on line 10 where the parser finally realizes something is wrong.

Common causes:

  • Missing colon after if, for, while, def, class, else, elif, try, except, with.
  • Unmatched parentheses, brackets, or quotes.
  • Using = instead of == in conditions.
  • Python 2 syntax in Python 3. print "hello" instead of print("hello").
  • Missing commas in lists, dicts, or function arguments.
  • Using reserved keywords as variable names.
  • Invalid f-string expressions.

Fix 1: Add the Missing Colon

The most common cause. Control structures require a colon at the end:

Broken:

if x > 10
    print("big")

for i in range(5)
    print(i)

def greet(name)
    return f"Hello, {name}"

class User
    pass

Fixed:

if x > 10:
    print("big")

for i in range(5):
    print(i)

def greet(name):
    return f"Hello, {name}"

class User:
    pass

Every if, elif, else, for, while, def, class, try, except, finally, and with statement must end with :.

Fix 2: Fix Unmatched Parentheses and Brackets

An unclosed (, [, or { causes a SyntaxError, often on a later line:

Broken:

data = {
    "name": "Alice",
    "age": 30
# Missing closing }

print("done")  # SyntaxError appears HERE, not on the dict

Fixed:

data = {
    "name": "Alice",
    "age": 30
}

print("done")

Tip: Count your brackets. Most editors highlight matching brackets. If the error points to a line that looks correct, check previous lines for unclosed brackets.

Common case — multi-line function call:

result = some_function(
    arg1,
    arg2,
    arg3
# Missing )

next_line = "hello"  # Error appears here

Pro Tip: When the SyntaxError points to a line that looks perfectly valid, the bug is almost always on a previous line — usually an unclosed parenthesis, bracket, or string. Start from the error line and scan backwards.

Fix 3: Fix Python 2 vs Python 3 Syntax

If you are running Python 3 with Python 2 code:

print statement (Python 2) → print function (Python 3):

# Python 2 (SyntaxError in Python 3):
print "Hello"

# Python 3:
print("Hello")

Integer division:

# Python 2: 5 / 2 = 2 (integer division)
# Python 3: 5 / 2 = 2.5 (float division)
# Python 3: 5 // 2 = 2 (integer division)

except syntax:

# Python 2 (SyntaxError in Python 3):
except ValueError, e:

# Python 3:
except ValueError as e:

raise syntax:

# Python 2:
raise ValueError, "message"

# Python 3:
raise ValueError("message")

Check your Python version: python --version. If Python itself is not found, see Fix: python command not found.

Fix 4: Fix Assignment vs Comparison

Using = (assignment) where == (comparison) is expected:

Broken:

if x = 10:  # SyntaxError — cannot assign in if condition
    print("ten")

Fixed:

if x == 10:
    print("ten")

Walrus operator (Python 3.8+):

If you intentionally want to assign AND compare:

if (n := len(items)) > 10:
    print(f"Too many items: {n}")

The walrus operator := is valid in Python 3.8+. In older versions, it causes a SyntaxError.

Fix 5: Fix F-String Syntax Errors

F-strings have special parsing rules:

Broken — backslash inside f-string expression (before Python 3.12):

name = f"{'\\n'.join(items)}"  # SyntaxError in Python < 3.12

Fixed — use a variable:

newline = "\n"
name = f"{newline.join(items)}"

Broken — unmatched braces:

msg = f"Value is {x"   # Missing closing }
msg = f"Use {{x}}"     # Wrong — {{ is an escaped brace

Fixed:

msg = f"Value is {x}"
msg = f"Use {{{x}}}"   # Literal { + value + literal }

Broken — nested quotes:

msg = f"Hello {"world"}"  # SyntaxError in Python < 3.12

Fixed:

msg = f"Hello {'world'}"  # Use different quotes inside
# Or in Python 3.12+:
msg = f"Hello {"world"}"  # Now valid

Fix 6: Fix Reserved Keyword Usage

Using Python keywords as variable or function names:

class = "Math"        # SyntaxError — 'class' is reserved
return = 42           # SyntaxError — 'return' is reserved
import = "data.csv"   # SyntaxError — 'import' is reserved

Python reserved keywords:

False, None, True, and, as, assert, async, await, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield

Fix — use a different name:

class_name = "Math"
return_value = 42
import_path = "data.csv"

Common Mistake: Using type, list, dict, str, int, id, input, print, format as variable names. These are not keywords (no SyntaxError), but they shadow built-in functions, causing subtle bugs later. For example, list = [1,2,3] means you can no longer call list().

Fix 7: Fix Missing Commas

Missing commas in collections, function calls, or multi-line expressions:

Broken — missing comma in list:

items = [
    "apple"
    "banana"  # SyntaxError or silent string concatenation!
    "cherry"
]

Python concatenates adjacent string literals: "apple" "banana" becomes "applebanana". This is not a SyntaxError but is almost certainly a bug.

Fixed:

items = [
    "apple",
    "banana",
    "cherry",
]

Broken — missing comma in function call:

result = my_function(
    arg1
    arg2  # SyntaxError
)

Fixed:

result = my_function(
    arg1,
    arg2,
)

Trailing commas are valid in Python and recommended for multi-line structures — they make diffs cleaner.

Fix 8: Fix Multi-Line String Issues

Broken — unclosed string:

message = "Hello
World"  # SyntaxError — string not closed

Fixed — use triple quotes for multi-line:

message = """Hello
World"""

Or use explicit newline:

message = "Hello\nWorld"

Or parenthesized string concatenation:

message = (
    "Hello "
    "World"
)

For indentation-related syntax issues, see Fix: Python IndentationError.

Still Not Working?

If you cannot find the syntax error:

Use Python’s -c flag to test snippets:

python3 -c "if True: print('ok')"

Use a linter. pylint, flake8, or ruff catch syntax errors with better messages:

pip install ruff
ruff check app.py

Check for invisible characters. Copy-pasting from web pages can introduce zero-width spaces or non-breaking spaces:

import re
with open("app.py", "rb") as f:
    content = f.read()
    non_ascii = [(i, b) for i, b in enumerate(content) if b > 127]
    print(non_ascii)

Check for mixed tabs and spaces. Python 3 does not allow mixing tabs and spaces for indentation. Configure your editor to use spaces only:

python3 -tt app.py  # Warns about tab/space mixing

Check the encoding declaration. Non-UTF-8 files might need an encoding header:

# -*- coding: utf-8 -*-

If the error is about imports rather than syntax, see Fix: Python ModuleNotFoundError. If the file has correct syntax but wrong indentation, see Fix: Python IndentationError.

For ValueError during type conversions (not syntax errors), see Fix: Python ValueError: invalid literal for int().

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles