TypeError: got an unexpected keyword argument (tested fix)
TypeError: f() got an unexpected keyword argument 'x' means you passed x=... to a function that has no parameter called x. We reproduced 6 causes in Python 3.13 and tested each fix.
1. The function has no parameter with that name
A keyword argument must match a parameter name exactly, including case:
def connect(host, port=5432):
return f"{host}:{port}"
for call in ["connect('db', prot=5433)", "connect('db', Port=5433)", "connect(host='db', timeout=3)"]:
try:
eval(call)
except TypeError as e:
print(f"{call:30} TypeError: {e}")
Output:
connect('db', prot=5433) TypeError: connect() got an unexpected keyword argument 'prot'
connect('db', Port=5433) TypeError: connect() got an unexpected keyword argument 'Port'. Did you mean 'port'?
connect(host='db', timeout=3) TypeError: connect() got an unexpected keyword argument 'timeout'
Python 3.13 adds a Did you mean hint for close matches, but not for every typo: swapped letters (prot) got no hint here. Python 3.11 (tested on python:3.11-alpine) prints the same three errors with no hints at all.
2. Standard-library typos and removed arguments
import json
try:
json.loads('{"a": 1}', encoding="utf-8") # removed in Python 3.9
except TypeError as e:
print("json.loads:", e)
try:
print("x", "y", seperator="-") # typo of sep
except TypeError as e:
print("print:", e)
try:
open("/tmp/uk/f.txt", "w", newlines="") # it's newline
except TypeError as e:
print("open:", e)
Output:
json.loads: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'
print: print() got an unexpected keyword argument 'seperator'
open: open() got an unexpected keyword argument 'newlines'. Did you mean 'newline'?
json.loads(..., encoding=) was removed in Python 3.9. Notice the error names JSONDecoder.__init__, not json.loads, because loads forwards unknown **kw to the decoder class. When the name in the error isn't the function you called, look for that kind of forwarding. The same happens when a library upgrade drops an argument.
3. Check which keywords a function accepts
import inspect, json
print(inspect.signature(json.loads))
def connect(host, port=5432): pass
print(inspect.signature(connect))
Output:
(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
(host, port=5432)
inspect.signature() (or help(f)) shows the real parameter names for the version you have installed, which may differ from the docs or tutorial you are reading.
4. super().__init__() passed an argument the parent doesn't take
class Base:
def __init__(self, name):
self.name = name
class Child(Base):
def __init__(self, name, color="red"):
super().__init__(name, color=color) # Base doesn't take color
try:
Child("box")
except TypeError as e:
print("TypeError:", e)
class Child(Base):
def __init__(self, name, color="red"):
super().__init__(name) # pass only what Base accepts
self.color = color
c = Child("box"); print(c.name, c.color)
Output:
TypeError: Base.__init__() got an unexpected keyword argument 'color'
box red
5. A decorator wrapper without **kwargs
def log(func):
def wrapper(*args): # forwards positionals only
return func(*args)
return wrapper
@log
def fetch(url, timeout=5):
return f"{url} t={timeout}"
try:
fetch("x", timeout=1)
except TypeError as e:
print("TypeError:", e)
def fetch2(url, **kwargs): # accept and ignore extras on purpose
return f"{url} extras={kwargs}"
print(fetch2("x", timeout=1, retries=2))
Output:
TypeError: log.<locals>.wrapper() got an unexpected keyword argument 'timeout'
x extras={'timeout': 1, 'retries': 2}
If the error names wrapper, the decorator only forwards *args; add **kwargs. Accepting **kwargs in your own function is fine when ignoring extras is intended, but it also hides typos.
6. Unpacking a dict with extra keys: User(**row)
from dataclasses import dataclass
@dataclass
class User:
name: str
row = {"name": "ann", "age": 30} # API/JSON row has extra keys
try:
User(**row)
except TypeError as e:
print("TypeError:", e)
import dataclasses
fields = {f.name for f in dataclasses.fields(User)}
print(User(**{k: v for k, v in row.items() if k in fields}))
Output:
TypeError: User.__init__() got an unexpected keyword argument 'age'
User(name='ann')
JSON and API rows often carry more keys than your class has fields. Filter the dict down to the accepted names first. Related: got multiple values for argument and takes 1 positional argument but 2 were given.
Frequently asked questions
How do I see which keyword arguments a function accepts?
Run inspect.signature(f) or help(f) in the Python version you actually use.
Why does json.loads say unexpected keyword argument 'encoding'?
The encoding argument was removed in Python 3.9. Delete it; loads() accepts str and bytes directly.
How do I pass a dict with extra keys to a class?
Filter it first: {k: v for k, v in row.items() if k in accepted_names}, then call Cls(**filtered).
Written with AI assistance. Measured on 2026-10-22 on Debian with Python 3.13.5 (hint behaviour also checked on python:3.11-alpine): typos and case, json.loads encoding=, print and open typos, inspect.signature, super().__init__, decorator wrappers and dataclass **dict unpacking. Every block was run verbatim and its output pasted unedited. PlainHeaders is our extension; Python is free.