SyntaxError, what it means and how to fix it

A SyntaxError means the program never ran: Python reads the whole file's grammar first, and this code does not parse. The message includes the file, the line, and a caret under the offending spot, but with an important catch: the parser reports where it got stuck, which for unclosed brackets and quotes is the line after the real mistake, or the end of the file. Trust the caret as a neighborhood, not an address.

What it looks like

if score > 50
    print("pass")

Traceback (most recent call last):
  File "main.py", line 1
    if score > 50
                 ^
SyntaxError: expected ':'

# fixed: the colon ends the if header
if score > 50:
    print("pass")

The fix, in order

  1. Read the caret, then look one line up. Missing colons, unclosed parentheses, and unterminated strings are only detected when the parser reaches the next line. If the flagged line looks innocent, the line above it is the crime scene.
  2. Check the greatest hits first: a missing colon after if/for/while/def/class/else/elif/try; = used where == was meant in a condition; brackets that do not pair; a string quote left open.
  3. Match the message to its specific wording. Modern Python names the problem precisely: “expected ':'”, “'(' was never closed”, “unmatched ')'”, “cannot assign to literal”. The wording tells you which greatest hit applies.
  4. Suspect the version when valid-looking code fails. f-strings need Python 3.6+, the walrus operator 3.8+, match statements 3.10+. Code copied from a tutorial failing on an old interpreter is a version mismatch; check python --version against where you run it (editor, terminal, and server can all differ).
  5. Copy-paste hazards: text pasted from web pages can carry smart quotes and non-breaking characters that look like code but are not ASCII. Retype the flagged line by hand if it visually refuses to be wrong.

If it still happens

If the error appears at the very end of the file (“unexpected EOF”), a bracket or triple-quoted string opened somewhere above was never closed. Count opens and closes per block, or comment out sections until the error moves; the block where it stops moving contains the imbalance.

Common questions

Why does the error point at a line that looks correct? The parser reports where it first became certain something was wrong, which is often the token after the mistake. A missing colon is discovered at the next line's start; an unclosed bracket at the closing context or EOF. Reading the line above the caret first is the standard habit for this error.

What's the difference between SyntaxError and IndentationError? IndentationError is a subclass of SyntaxError specifically about leading whitespace: tabs and spaces mixed, or a block indented inconsistently. The fix lives in the invisible characters at line starts rather than in the visible code.

Related errors

IndentationError · ImportError · NameError: name is not defined