Skip to main content

How to Resolve SyntaxError: positional argument follows keyword argument in Python

The SyntaxError: positional argument follows keyword argument is a common error in Python that arises when calling functions. It signals that you've violated Python's rule about the order of arguments: positional arguments must always come before keyword arguments.

This guide explains why this rule exists and how to fix the error.

Understanding Positional vs. Keyword Arguments

When calling a function in Python, you can pass arguments in two main ways:

  • Positional Arguments: These are matched to function parameters based on their order. The first argument you pass corresponds to the first parameter, the second argument to the second parameter, and so on.
    def greet(name, message):
    print(f"{message}, {name}!")

    greet("Alice", "Hello") # "Alice" matches 'name', "Hello" matches 'message'
  • Keyword Arguments: These are matched to function parameters based on their name, using the parameter_name=value syntax. The order of keyword arguments generally doesn't matter (as long as they come after positional ones).
    greet(message="Hi", name="Bob") # Order doesn't matter here
    greet(name="Charlie", message="Good morning")

The Error: Why Order Matters

Python enforces the rule that all positional arguments must come before any keyword arguments in a function call.

Error Example:

def get_employee(first, last, salary):
return {'first': first, 'last': last, 'salary': salary}

# This causes the error because the positional argument '100'
# comes AFTER the keyword argument last='Nolan'
# result = get_employee('Tom', last='Nolan', 100)
# ⛔️ SyntaxError: positional argument follows keyword argument

Once you start using keyword arguments, Python assumes all subsequent arguments will also be keyword arguments. If it encounters a positional argument after a keyword argument, it gets confused about which parameter the positional argument corresponds to, hence the SyntaxError.

The standard solution is to ensure all positional arguments are listed first, followed by any keyword arguments:

def get_employee(first, last, salary):
return {'first': first, 'last': last, 'salary': salary}

# Correct: Positional ('Tom') first, then keyword arguments
result = get_employee('Tom', last='Nolan', salary=100)
print(result) # Output: {'first': 'Tom', 'last': 'Nolan', 'salary': 100}

# Also correct (order of keyword args doesn't matter among themselves):
result2 = get_employee('Tom', salary=100, last='Nolan')
print(result2) # Output: {'first': 'Tom', 'last': 'Nolan', 'salary': 100}

Solution 2: Use Only Positional Arguments

If appropriate, you can simply pass all arguments positionally, ensuring they are in the correct order as defined by the function:

def get_employee(first, last, salary):
return {'first': first, 'last': last, 'salary': salary}

result = get_employee('Tom', 'Nolan', 100) # All positional
print(result) # Output: {'first': 'Tom', 'last': 'Nolan', 'salary': 100}

Solution 3: Use Only Keyword Arguments

You can also choose to pass all arguments as keyword arguments. This makes the call very explicit but can be more verbose:

def get_employee(first, last, salary):
return {'first': first, 'last': last, 'salary': salary}

result = get_employee(salary=100, first='Alice', last='Smith') # All keyword
print(result) # Output: {'first': 'Alice', 'last': 'Smith', 'salary': 100}

Important Note: Order of Positional Arguments Still Matters

Even when placing keyword arguments correctly after positional ones, ensure the positional arguments themselves are in the right order corresponding to the function definition. Mixing them up can lead to a different error (TypeError: ... got multiple values for argument ...):

def get_employee(first, last, salary):
return {'first': first, 'last': last, 'salary': salary}

# Incorrect: '100' is passed positionally for 'last',
# but 'last' is also given as a keyword argument.
# result = get_employee('Tom', 100, last='Nolan')
# ⛔️ TypeError: get_employee() got multiple values for argument 'last'

The fix here is usually to use either all positional or correctly mixed positional/keyword arguments (as shown in previous solutions).

Parameter Order in Function Definitions (Positional, Default, *args, **kwargs)

It's helpful to remember the required order of parameter types when defining a function, which mirrors the calling convention:

  1. Standard Positional Parameters: (e.g., a, b)
  2. Default Argument Parameters: (e.g., c=10, d='default')
  3. *args: Collects any extra positional arguments into a tuple.
  4. Keyword-Only Parameters: (defined after * or *args, e.g., *, kw_only1, kw_only2=None)
  5. **kwargs: Collects any extra keyword arguments into a dictionary.
def example_func(pos1, pos2, default1='a', *args, kw_only1, kw_only2='b', **kwargs):
print(f"pos1: {pos1}, pos2: {pos2}")
print(f"default1: {default1}")
print(f"args: {args}")
print(f"kw_only1: {kw_only1}")
print(f"kw_only2: {kw_only2}")
print(f"kwargs: {kwargs}")

example_func(1, 2, 'X', 10, 20, kw_only1='required', extra='value')

Output:

pos1: 1, pos2: 2
default1: X
args: (10, 20)
kw_only1: required
kw_only2: b
kwargs: {'extra': 'value'}

Conclusion

The SyntaxError: positional argument follows keyword argument is a fundamental rule in Python function calls.

To resolve it, simply ensure that all positional arguments are listed before any keyword arguments.

Understanding the difference between positional and keyword arguments and adhering to this order will prevent this common syntax error.