This FAQ is designed to work as a standalone article. The Open in Colab button above opens an optional notebook where you can run the examples one at a time, inspect the errors, and try each repair.
A class call can look perfectly readable and still fail because one supplied keyword does not match the active method signature. The error is small, but it reveals how classes, methods, self, parameters, and arguments fit together.
Short answer
got an unexpected keyword argument 'level' means the call supplied a named argument, level, but the function or method Python called has no parameter with that exact name. Compare the call with the active definition. Correct a typo, remove data that does not belong, or declare and store a real parameter.
For ordinary instance methods, also verify that self is the first parameter. A missing self changes how every visible argument is matched and may produce this error or a related message such as got multiple values for argument.
What does the error actually mean?
The error is a TypeError because Python found a mismatch between a callable’s definition and the arguments used to call it.
Focus on the final part:
got an unexpected keyword argument 'level'
This says:
The call used the keyword level.
Python inspected the callable’s accepted parameters.
No parameter with that exact name could receive the value.
“Unexpected” describes the function signature, not the programmer. Python is reporting that the call and definition do not currently agree.
Start with the named callable
The full message often identifies where Python tried to send the argument:
Workshop.__init__()
The dot indicates that __init__ belongs to Workshop. Search for that class and method definition before searching the entire project.
TipUse the exact rejected name
Copy level directly from the message. Look for it in both the call and the definition. This avoids overlooking a small difference such as level, levels, or Level.
How do classes and instances reach __init__?
A class defines a kind of object. An instance is one object created from that class.
Workshop is the class. python_basics and data_lab refer to two separate instances. Each instance stores its own title and level attributes.
When Python evaluates this call:
Workshop("Python Basics", "beginner")
it performs these beginner-relevant steps:
Create a new Workshop instance.
Call Workshop.__init__ to initialize that instance.
Pass the new instance automatically as the first argument.
Match the caller’s remaining arguments to title and level.
Return the initialized instance from the class call.
__init__ is commonly called a constructor in everyday Python teaching. More precisely, it initializes an instance after Python creates it. That distinction becomes useful later, but it does not change this debugging routine.
The class call supplies two visible arguments. Python adds the new instance for self before it calls __init__.
The method can work with the particular instance through self. Here, self.title and self.level mean the attributes of the workshop instance that received the method call.
A bound method receives the instance automatically
The first form is normal application code. Python looks up make_label on the class and binds workshop to the method as its first argument. The second form makes that normally automatic argument visible.
This is why an instance method needs a first parameter for the instance.
What is self, and why must it come first?
self is the conventional name for the instance currently receiving a method call.
class Counter:def__init__(self):self.value =0def increment(self, amount):self.value =self.value + amount
In this call:
counter = Counter()counter.increment(2)
Python binds:
counter to self automatically; and
the visible argument 2 to amount.
After the method finishes, counter.value is 2.
self is not a reserved Python keyword. A different parameter name can work, but using self is a strong convention that makes Python code recognizable to other developers. Put it first in ordinary instance methods.
Do all functions inside a class receive self?
Ordinary instance methods do. Python also provides @classmethod, whose first parameter is conventionally named cls, and @staticmethod, which receives no automatic instance or class argument.
Do not omit self accidentally to make an instance method static. If a utility truly belongs with a class but does not use an instance, mark that choice explicitly:
class Temperature:@staticmethoddef celsius_to_fahrenheit(value):return value *9/5+32print(Temperature.celsius_to_fahrenheit(value=20))
For beginner class designs, start with ordinary instance methods and self. Use a plain function when the behavior does not need object state and does not naturally belong to a class.
What happens when self is missing?
Consider this broken initializer:
class BrokenWorkshop:def__init__(title, level): title.level = levelworkshop = BrokenWorkshop(title="Python", level="beginner")
A common Python result is:
TypeError: BrokenWorkshop.__init__() got multiple values for argument 'title'
Why multiple values instead of unexpected keyword?
Python automatically sends the new instance as the first positional argument.
Because the method forgot self, the first declared parameter is title.
The automatic instance is therefore matched to title.
The call also explicitly supplies title="Python".
Python now has two values competing for the same parameter.
The repair is:
class Workshop:def__init__(self, title, level):self.title = titleself.level = level
Missing self belongs to the same family of argument-binding problems, but the exact error depends on the parameter names and how the method is called. You may see:
got multiple values for argument ...;
takes ... positional arguments but ... were given; or
got an unexpected keyword argument ....
WarningDo not repair only the error wording
Adding, removing, or renaming a keyword until the message disappears can leave the class with the wrong design. First make sure every instance method has self, then compare the remaining parameters with the caller-supplied arguments.
title is required because it has no default value.
level is optional because its default is "beginner".
The same matching rules apply to methods after Python handles the automatic instance argument.
Positional arguments use order
make_label("Python", "intermediate")
Python matches the first value to title and the second to level.
Keyword arguments use names
make_label(title="Python", level="intermediate")
Python matches each value to the parameter with that exact name. Keyword arguments make many calls easier to read and allow the supplied keywords to appear in a different order:
make_label(level="intermediate", title="Python")
Positional and keyword arguments can be mixed carefully
make_label("Python", level="intermediate")
Positional arguments must appear before keyword arguments in a call. A parameter must not receive two values:
make_label("Python", title="Data Science")
This raises:
TypeError: make_label() got multiple values for argument 'title'
Compare the common messages
Message fragment
Matching problem
First check
unexpected keyword argument 'level'
No accepted parameter is named level.
Compare spelling and the definition.
missing 1 required positional argument: 'title'
No value reached required parameter title.
Supply it or decide whether it needs a default.
got multiple values for argument 'title'
Two arguments both reached title.
Check mixed arguments and missing self.
takes 2 positional arguments but 3 were given
More positional values arrived than parameters can receive.
Remember the automatic instance for methods.
Which fix matches the program?
There is no single repair. Choose the one that matches the program’s meaning.
The default lets a caller omit level, while an explicit keyword can override it.
Fix E: Add self to an instance method
class Workshop:def describe(self, prefix):returnf"{prefix}: {self.title}"
After self receives the instance, prefix can correctly receive the visible argument:
print(workshop.describe(prefix="Course"))
Do not use **kwargs as a universal patch
This version accepts any keyword:
class Workshop:def__init__(self, title, **kwargs):self.title = title
It also silently accepts a typo such as levle="beginner" unless the method validates kwargs. That can move the bug farther from its cause. Use **kwargs when the design genuinely needs to collect or forward flexible named arguments, not merely to hide a useful error.
How can I inspect what a class accepts?
The most reliable comparison uses the running code, not memory.
Read the definition
Find class Workshop, then inspect def __init__(...) and the method named in the traceback. Write the declared parameter names beside the supplied keyword names.
Ask Python for the signature
The standard-library inspect module can display accepted parameters:
The class signature shows what callers normally supply. The unbound Workshop.__init__ signature includes self. The bound workshop.describe signature omits the already supplied instance.
help(Workshop) and editor parameter hints can also reveal a signature. For a third-party class, compare documentation with the version installed in the current environment.
Rerun a changed class in notebooks
Editing a class cell does not replace the class in a running Colab or Jupyter runtime until that cell executes again.
If the displayed definition includes level but the running class still rejects it:
Run the class-definition cell again.
Recreate the instance.
Run the failing call again.
If execution history is unclear, restart and run all cells from the top.
Workshop(title="Python", difficulty="easy") raises an unexpected keyword error because there is no field named difficulty. Add a real field or use the correct existing name. Continue with Use Dataclasses for Value-Like Objects for deeper practice.
A child class may replace its parent’s initializer
class Course:def__init__(self, title):self.title = titleclass OnlineCourse(Course):def__init__(self, url):self.url = url
OnlineCourse.__init__ currently accepts only url. If an online course needs both values, declare both and initialize the parent part deliberately:
class OnlineCourse(Course):def__init__(self, title, url):super().__init__(title)self.url = url
Inheritance is a later topic, but the immediate debugging habit is the same: inspect the initializer that Python actually calls. See Choose Composition Before Inheritance when you are ready to study parent and child classes.
A repeatable debugging routine
Use this routine for constructors, methods, ordinary functions, dataclasses, and library APIs.
Read the last traceback line. Record the callable and rejected keyword.
Find the call. List every positional and keyword argument supplied.
Find the active definition. Inspect __init__ or the named method.
Account for the automatic instance. An instance method normally begins with self, which Python supplies.
Match values to parameters. Use order for positional arguments and exact names for keyword arguments.
Choose a meaning-based fix. Correct a typo, change the call, declare real data, add a default, or restore self.
Rerun the definition if needed. Notebook state may still contain an older class.
Change one thing and test again. A different error is new evidence, not a reason to change several unrelated lines.
NoteMake the problem small
Copy only the class definition and one failing call into a fresh cell. Replace large data with short strings. If the small version works, restore one removed piece at a time until the mismatch returns.