PythonMastery
reference 3 min read · lesson 48 of 60 in Errors

TypeError: got an unexpected keyword argument

1 · The lesson

read

What this error means

You called a function with name=value, and the function has no parameter called name. Python won't guess what you meant or silently drop it — an unknown keyword is an error, full stop.

Since Python 3.13, the message often ends with a suggestion. Read it before anything else; it is right most of the time.

When you see it

python
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    print(apply_discount(80, rat=0.15))
          ~~~~~~~~~~~~~~^^^^^^^^^^^^^^
TypeError: apply_discount() got an unexpected keyword argument 'rat'. Did you mean 'rate'?
python
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    df.to_csv("orders.csv", line_terminator="\n")
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../site-packages/pandas/util/_decorators.py", line 333, in wrapper
    return func(*args, **kwargs)
TypeError: NDFrame.to_csv() got an unexpected keyword argument 'line_terminator'. Did you mean 'lineterminator'?

The second one is code that worked for years and broke on a pandas upgrade.

Why it happens

Three causes cover nearly every case:

1. A typo in the keyword name. rat= for rate=, maxsplits= for maxsplit=, sepp= for sep=.
2. The library renamed or removed the parameter. Libraries deprecate a name, warn for a release or two, then delete it. If you ignored the FutureWarning, this error is where it ends up.
3. The class's __init__ doesn't accept that field. A dataclass without that field declared, or a subclass whose own __init__ takes fewer arguments than the parent's.

python
from dataclasses import dataclass

@dataclass
class Invoice:
    number: str
    amount: float

inv = Invoice("INV-1042", 250.0, currency="GBP")
# TypeError: Invoice.__init__() got an unexpected keyword argument 'currency'

How to fix it

For a typo, take the suggestion. If there isn't one, print the real signature:

python
import inspect

def apply_discount(price, rate):
    return round(price * (1 - rate), 2)

print(inspect.signature(apply_discount))    # (price, rate)
print(apply_discount(80, rate=0.15))        # 68.0

For a library rename, use the new name and check the changelog for others. A few renames you will meet in older tutorials:

Old keywordNew keywordWhere
line_terminator=lineterminator=pandas to_csv (removed in 2.0)
error_bad_lines=Falseon_bad_lines="skip"pandas read_csv (removed in 2.0)
sparse=Falsesparse_output=Falsescikit-learn OneHotEncoder (removed in 1.4)
python
import io
import pandas as pd

raw = io.StringIO("order,amount\nA1,19.99\nA2,45.00,EXTRA\nA3,8.50\n")
df = pd.read_csv(raw, on_bad_lines="skip")   # not error_bad_lines=False
print(df)

If you can't change the code yet, pin the version that still accepts the old name in requirements.txt — and treat that as a debt, not a fix.

For a dataclass, declare the field. Give it a default if older callers don't pass it:

python
from dataclasses import dataclass

@dataclass
class Invoice:
    number: str
    amount: float
    currency: str = "GBP"

print(Invoice("INV-1042", 250.0, currency="EUR"))
print(Invoice("INV-1043", 99.0))

For a subclass, forward the arguments you don't handle. A subclass __init__ that lists only its own parameters cuts off everything the parent accepts:

python
class User:
    def __init__(self, name, email=None):
        self.name = name
        self.email = email

class Admin(User):
    def __init__(self, name, *, team="ops", **kwargs):
        super().__init__(name, **kwargs)     # email passes straight through
        self.team = team

hedy = Admin("Hedy", email="hedy@example.com", team="platform")
print(hedy.name, hedy.email, hedy.team)      # Hedy hedy@example.com platform
+ setup added so this can run · defines kwargs
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

kwargs = _AutoMock('kwargs')

When you'd actually see this in real code

  • A pandas or scikit-learn upgrade in CI, where a notebook that ran fine last month now fails on a read_csv or an encoder call.
  • Copying an answer written for a newer library version into a project pinned to an older one. The error goes both ways: new names don't exist in old releases either.
  • Passing a config dict straight in with **settings, where the dict has one key the function doesn't know (often a stray "debug" or "name").
  • Adding a field to an API payload and building a dataclass from it with Invoice(**row). Every unexpected column in the row becomes an unexpected keyword.
  • A decorator whose wrapper is def wrapper(x): instead of def wrapper(*args, **kwargs):, so every keyword argument hits the wrapper and stops there.

See Also

Found this useful? Share it with a friend who’s learning Python.