Skip to main content

How to Resolve Python "SyntaxError: invalid syntax" with match/case Statements

Python 3.10 introduced a powerful feature called Structural Pattern Matching, implemented using the match and case keywords. If you attempt to use this syntax but encounter a SyntaxError: invalid syntax, it typically means you're either running an incompatible (older) version of Python or there's a syntax mistake in or around your match/case block.

This guide explains the requirements for using match/case and how to diagnose and fix common syntax errors.

Understanding match/case (Structural Pattern Matching)

Introduced in Python 3.10, the match/case statement provides a way to compare a value (the subject) against several possible patterns (case) and execute code based on the first successful match. It's similar to switch statements in other languages but much more powerful due to pattern matching capabilities.

Basic Syntax:

match subject_variable:
case pattern_1:
# Action for pattern 1
print("Matched pattern 1")
case pattern_2:
# Action for pattern 2
print("Matched pattern 2")
case _: # Wildcard (optional default)
# Action if no other pattern matches
print("No specific match")

Cause 1: Using Python Version Older Than 3.10

This is the most common reason for the SyntaxError when first trying match/case. The syntax simply did not exist before Python 3.10.

# Error Scenario (when run with Python 3.9 or older)

status_code = 404

def get_message(status):
# The line below causes the error in < Python 3.10
match status: # ⛔️ SyntaxError: invalid syntax
case 404:
return "Not Found"
case 200:
return "OK"
case _:
return "Other"

try:
# This call won't even be reached if the syntax error occurs during parsing
message = get_message(status_code)
print(message)
except SyntaxError as e:
print(f"Caught SyntaxError (likely due to Python version < 3.10): {e}")
except Exception as e:
print(f"Caught other error: {e}") # Catch other potential errors too

The Python interpreter sees the match keyword and, if it's an older version, doesn't recognize it as valid syntax.

Solution 1: Check and Update Your Python Version

Verify the Python version you are using to run the script.

  1. Open your terminal or command prompt.
  2. Run:
    python --version
    # Or, depending on your system setup:
    python3 --version
    py --version # Windows
  3. If the output version is less than 3.10.0, you need to either:
    • Upgrade Python: Download and install the latest stable Python 3 version from python.org. Ensure your system's PATH and your project/IDE environment point to the new version.
    • Use an environment with Python 3.10+: If you use tools like pyenv or conda, switch to or create an environment using Python 3.10 or newer.
    • Rewrite the code: If upgrading is not possible, use alternative control flow structures (see next section).

Alternative for Older Python Versions (< 3.10)

If you cannot use Python 3.10+, you must rewrite the logic using traditional if/elif/else statements or dictionary lookups.

  • Using if/elif/else:
    def get_message_legacy(status):
    if status == 404:
    return "Not Found"
    elif status == 200:
    return "OK"
    elif status == 500:
    return "Server Error"
    else: # Default case
    return "Other"

    print(f"Legacy check (404): {get_message_legacy(404)}") # Output: Legacy check (404): Not Found
    print(f"Legacy check (999): {get_message_legacy(999)}") # Output: Legacy check (999): Other
  • Using Dictionary get(): Suitable when matching specific literal values.
    def get_message_dict(status):
    status_map = {
    404: "Not Found",
    200: "OK",
    500: "Server Error"
    }
    # Return the value from the dict, or the default message if key not found
    return status_map.get(status, "Other") # "Other" is the default

    print(f"Dict check (200): {get_message_dict(200)}") # Output: Dict check (200): OK
    print(f"Dict check (401): {get_message_dict(401)}") # Output: Dict check (401): Other

Cause 2: Syntax Errors Within the match/case Block

Even if using Python 3.10+, syntax errors within the match or case statements themselves will cause the SyntaxError.

Missing Colons (:)

Both the match subject line and every case pattern line must end with a colon (:).

# Error Scenario: Missing colon after 'match' or 'case'
value = "A"
try:
match value # ⛔️ SyntaxError: invalid syntax (expected ':')
case "A":
print("It's A")
except SyntaxError as e:
print(f"Error (missing colon): {e}")

try:
match value:
case "A" # ⛔️ SyntaxError: invalid syntax (expected ':')
print("It's A")
except SyntaxError as e:
print(f"Error (missing colon): {e}")

Incorrect Indentation

The action block following each case pattern: line must be indented, and all lines within that block must have consistent indentation.

# Error Scenario: Incorrect indentation
value = "B"
try:
match value:
case "A":
print("It's A")
case "B":
print("It's B") # ⛔️ IndentationError: expected an indented block
except IndentationError as e: # Or sometimes SyntaxError
print(f"Error (bad indent): {e}")

Invalid Case Patterns

While powerful, case patterns have rules. Using invalid expressions as patterns (e.g., function calls directly in the pattern) can cause errors. For basic use, focus on literals (numbers, strings), variable names (captures), wildcards (_), and simple structures.

Solution 2: Correct the match/case Syntax

Carefully review your match/case block against the standard syntax:

  • Ensure match subject: ends with a colon (:).
  • Ensure every case pattern: line ends with a colon (:).
  • Ensure the code block under each case is correctly and consistently indented.
  • Ensure your case patterns are valid (refer to Python documentation for complex patterns if needed).
# Correct Syntax Example
def process_value(value):
match value: # Colon after match
case 1: # Colon after case
print("Value is one") # Indented action
case "hello": # Colon after case
print("Value is hello") # Indented action
print("Another action") # Consistently indented
case _: # Colon after wildcard case
print("Other value") # Indented action

process_value(1)
process_value("hello")
process_value(99.9)

Output:

Value is one
Value is hello
Another action
Other value

Cause 3: Syntax Error Before the match Statement

Sometimes, a SyntaxError reported on the match line is actually caused by an error on a preceding line, such as an unclosed parenthesis, bracket, or quote. The parser gets confused and reports the error at the first keyword (match) it doesn't expect.

# Error Scenario: Unclosed parenthesis on the line before
my_list = [1, 2, 3 # ⛔️ Missing closing ']'

# Python might report the error on the 'match' line below
# because it didn't expect 'match' after the incomplete list definition.
# match some_variable:
# case ...

try:
eval("my_list = [1, 2, 3 \nmatch 5:\n case 5: pass") # Simulate multi-line parsing
except SyntaxError as e:
print(f"Error likely caused by preceding line: {e}") # Error might mention EOF or unexpected keyword

Solution 3: Check Preceding Code

If the syntax within your match/case block looks correct, carefully inspect the lines immediately before the match statement for:

  • Unclosed parentheses (, square brackets [, or curly braces {.
  • Unclosed quotes ' or ".
  • Other syntax errors.
note

Debugging Tip: Temporarily comment out the entire match/case block. If the SyntaxError disappears or moves to the line before where the match block started, the issue is in the preceding code.

Debugging Checklist

When facing SyntaxError: invalid syntax near match/case:

  1. Python Version: Are you running Python 3.10 or newer (python --version)?
  2. Colon after match: Does the match subject: line end with a colon?
  3. Colon after case: Does every case pattern: line end with a colon?
  4. Indentation: Is the code block under each case indented correctly and consistently?
  5. Pattern Validity: Are your case patterns valid (e.g., literals, variables, _)?
  6. Preceding Code: Is there a syntax error (like unclosed brackets/quotes) on the lines before the match statement?

Conclusion

The SyntaxError: invalid syntax when using match/case most often stems from:

  1. Using a Python version older than 3.10. Solution: Upgrade Python or use if/elif/else/dictionaries.
  2. Incorrect syntax within the match/case block itself (missing colons :, bad indentation). Solution: Correct the syntax according to the match subject: case pattern: action structure.
  3. A syntax error on a line preceding the match statement. Solution: Carefully review the code above the match block.

By verifying your Python version and carefully checking the syntax around and within your match/case statements, you can effectively resolve this error.