Fix: Python TypeError: missing required positional argument
Part of: Python Errors
Quick Answer
How to fix Python TypeError missing required positional argument caused by missing self, wrong argument count, class instantiation errors, and decorator issues.
The Error
You call a function or method and get:
TypeError: __init__() missing 1 required positional argument: 'name'Or variations:
TypeError: greet() missing 1 required positional argument: 'name'TypeError: process_data() missing 2 required positional arguments: 'data' and 'format'TypeError: send_email() missing 1 required positional argument: 'self'Python called a function or method but did not receive all the arguments it requires. The function expects more arguments than were provided.
Why This Happens
Python functions have a fixed set of required parameters (those without default values). When you call a function without providing all required arguments, Python raises TypeError before the function body even executes. The signature check happens in the CPython interpreter’s argument-binding step, so the error is raised even if the function body would have crashed for another reason.
Method calls add a second layer of confusion. When you write instance.method(arg), Python turns it into Method.method(instance, arg) under the hood — self is the first positional argument, supplied implicitly by the descriptor protocol. When you write ClassName.method(arg), Python does not supply self, so your arg lands in the self slot and the next parameter is missing. The error message says missing 1 required positional argument: 'self' or 'name' depending on whether you also forgot to instantiate the class.
A third source is signature mismatch across boundaries: callback functions passed to map, filter, sorted, threading.Thread, an async framework, or a decorator may be called with a different argument count than you intended. Python does not check the signature at registration time; it discovers the mismatch only when the callback fires. This is why this error frequently surfaces only in production code paths that tests did not exercise.
Common causes:
- Missing
selferror. You called an instance method on the class itself instead of on an instance. - Wrong number of arguments. You forgot to pass one or more required arguments.
- Missing parentheses. You referenced the class instead of instantiating it.
- Decorator issue. A decorator consumed an argument or changed the function signature.
- Callback signature mismatch. A callback function expects more arguments than the caller provides.
- Refactored function. The function signature changed but not all call sites were updated.
- Async vs sync mismatch. An async function called without
awaitreturns a coroutine that you then try to invoke as if it were the real callable.
In Production: Incident Lens
TypeError: missing required argument is the canonical “this slipped past tests” production error. The function compiles, the import succeeds, the application starts cleanly — and then the first user request that exercises the affected code path returns a 500. Unlike ImportError or SyntaxError, this only triggers when the broken call site is actually invoked, so it can lurk in cold paths (admin endpoints, scheduled jobs, error handlers) for weeks.
How it surfaces: an alert from Sentry, Rollbar, or your logging stack shows a spike of TypeError: foo() missing 1 required positional argument: 'bar'. The stack trace points at the call site. The triggering request is usually identifiable from the breadcrumb trail — often a payload variant or an endpoint that tests did not cover. In Django this manifests as a 500 with the error in traceback.format_exc() in the logs; in FastAPI it becomes a Internal Server Error JSON response and a logged exception.
Blast radius: scoped to the specific code path. If the error lives in a request handler, every request that reaches that handler fails. If it lives in a background task, the task fails and (depending on the framework) gets retried, which may amplify the error rate. If it lives in an error handler itself, you get a secondary failure that masks the original — debugging gets harder because the visible exception is from the handler, not the cause.
Monitoring signal: the high-signal alerts come from your APM (Sentry, Datadog APM, New Relic). Alert on new exception types appearing within 5 minutes of a deploy and on any TypeError whose count crosses a deploy boundary. Pair this with endpoint-level error rate monitoring — if /api/admin/export jumps from 0 to 5% error rate in the minute after a deploy, you have your culprit. Sentry’s release tracking attributes the regression to the exact commit, which is the data you actually want at 3am.
Recovery sequence: rollback first, debug second. The error is deterministic for the affected code path, so leaving the broken version running just generates more noise without giving you new information. Roll the deploy back, confirm the error rate returns to baseline, then reproduce the call locally with the same payload that triggered the production failure. Add the missing kwarg (or restore the deleted parameter), write a test that hits the endpoint with that payload, and ship the fix in a follow-up PR.
Postmortem preventive: the durable fix is type checking and integration tests, not stricter code review. Run mypy --strict (or at minimum --disallow-untyped-defs and --check-untyped-defs) in CI so that signature changes are flagged at the type-checker level before they reach review. Add an integration test for every public endpoint that posts a realistic payload — fixture-based tests with the real JSON your API receives catch this class of bug reliably. For background jobs and rare code paths, schedule a synthetic invocation in a staging-like environment so the cold path runs at least once per day with the new code.
Fix 1: Fix the “missing self” Error
The most common case. If the error says missing 1 required positional argument: 'self', you called a method on the class instead of an instance:
Broken:
class User:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}!"
# Calling on the class (wrong):
User.greet() # TypeError: greet() missing 1 required positional argument: 'self'Fixed — create an instance first:
user = User("Alice")
user.greet() # "Hello, Alice!"When you call user.greet(), Python automatically passes user as self. When you call User.greet(), there is no instance to pass as self, so it is missing.
Broken — forgot to instantiate:
class Database:
def __init__(self, url):
self.url = url
def connect(self):
print(f"Connecting to {self.url}")
# Missing parentheses — Database is the class, not an instance:
db = Database
db.connect() # TypeError: connect() missing 1 required positional argument: 'self'Fixed:
db = Database("postgresql://localhost/mydb")
db.connect() # WorksPro Tip: If you see
missing 1 required positional argument: 'self', the fix is almost always to changeClassName.method()toinstance.method(). Theselfargument is never passed explicitly by the caller — Python handles it when you call a method on an instance.
Fix 2: Pass All Required Arguments
Check the function signature and provide every argument that does not have a default value:
def send_email(to, subject, body):
print(f"Sending to {to}: {subject}")
# Missing arguments:
send_email("[email protected]")
# TypeError: send_email() missing 2 required positional arguments: 'subject' and 'body'
# Fixed — pass all arguments:
send_email("[email protected]", "Hello", "How are you?")Use keyword arguments for clarity:
send_email(
to="[email protected]",
subject="Hello",
body="How are you?"
)Add default values for optional parameters:
def send_email(to, subject="No Subject", body=""):
print(f"Sending to {to}: {subject}")
# Now only 'to' is required:
send_email("[email protected]") # WorksFix 3: Fix init Arguments
When creating instances, the error tells you what argument __init__ expects:
class Config:
def __init__(self, filepath, encoding="utf-8"):
self.filepath = filepath
self.encoding = encoding
# Missing filepath:
config = Config()
# TypeError: __init__() missing 1 required positional argument: 'filepath'
# Fixed:
config = Config("config.yaml")
config = Config(filepath="config.yaml", encoding="latin-1")Common in Django models:
# Django model
class Article(models.Model):
title = models.CharField(max_length=200)
# Creating without required field:
article = Article()
article.save()
# IntegrityError or TypeError depending on validationFor Django database errors, see Fix: Django OperationalError: no such table.
Fix 4: Fix Static and Class Methods
If a method does not need self, declare it as @staticmethod or @classmethod:
Broken — method does not use self but still requires it:
class MathHelper:
def add(a, b): # Missing 'self' parameter
return a + b
helper = MathHelper()
helper.add(2, 3)
# TypeError: add() takes 2 positional arguments but 3 were given
# (Python passed 'self' as the first argument, shifting a and b)Fixed — use @staticmethod:
class MathHelper:
@staticmethod
def add(a, b):
return a + b
MathHelper.add(2, 3) # Works — no self needed
helper = MathHelper()
helper.add(2, 3) # Also worksFixed — use @classmethod if you need the class:
class Config:
default_path = "/etc/config.yaml"
@classmethod
def from_default(cls):
return cls(cls.default_path)
def __init__(self, path):
self.path = path
config = Config.from_default() # Works — cls is passed automaticallyFix 5: Fix Callback and Lambda Arguments
When passing functions as callbacks, the callback signature must match what the caller expects:
Broken — callback expects more arguments than provided:
def on_complete(result, status):
print(f"Done: {result} ({status})")
# The caller only passes one argument:
results = [1, 2, 3]
list(map(on_complete, results))
# TypeError: on_complete() missing 1 required positional argument: 'status'Fixed — match the expected signature:
def on_complete(result):
print(f"Done: {result}")
list(map(on_complete, results))Or provide defaults:
def on_complete(result, status="success"):
print(f"Done: {result} ({status})")
list(map(on_complete, results)) # Works — status defaults to "success"Broken — sorted() key function with wrong signature:
def compare(a, b):
return a - b
# sorted() key takes one argument, not two:
sorted([3, 1, 2], key=compare)
# TypeError: compare() missing 1 required positional argument: 'b'Fixed:
sorted([3, 1, 2], key=lambda x: x) # Key takes one argumentFix 6: Fix Decorator Issues
Decorators can change how arguments are passed:
Broken — decorator that does not pass arguments through:
def my_decorator(func):
def wrapper(): # Missing *args, **kwargs!
print("Before")
func() # Missing arguments!
print("After")
return wrapper
@my_decorator
def greet(name):
print(f"Hello, {name}")
greet("Alice")
# TypeError: wrapper() takes 0 positional arguments but 1 was givenFixed:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Before")
result = func(*args, **kwargs)
print("After")
return result
return wrapper
@my_decorator
def greet(name):
print(f"Hello, {name}")
greet("Alice") # WorksAlways use *args, **kwargs in decorator wrappers to forward all arguments.
Common Mistake: Writing a decorator that works for functions with no arguments but breaks when applied to functions with arguments. Always use
*args, **kwargsin the wrapper function. Usefunctools.wrapsto preserve the original function’s name and docstring:from functools import wraps def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper
Fix 7: Fix Inheritance and super() Calls
When overriding methods in subclasses, make sure you pass the required arguments to super():
Broken:
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
class Dog(Animal):
def __init__(self, name):
super().__init__(name) # Missing 'species'!
# TypeError: __init__() missing 1 required positional argument: 'species'Fixed:
class Dog(Animal):
def __init__(self, name):
super().__init__(name, "Dog")Fix 8: Debug the Error
When the error is not obvious, inspect the function signature:
import inspect
# See the function signature:
print(inspect.signature(my_function))
# See all parameters:
for name, param in inspect.signature(my_function).parameters.items():
print(f"{name}: {param.kind.name}, default={param.default}")This shows you exactly which parameters are required and which have defaults.
Use IDE features:
Most IDEs (VS Code, PyCharm) show function signatures as you type. Hover over the function name to see the expected arguments.
Check for method vs function:
print(type(obj.method)) # <class 'method'> — self is passed automatically
print(type(MyClass.method)) # <class 'function'> — self must be passed manuallyIf you see function where you expect method, you are calling it on the class instead of an instance.
Still Not Working?
If you have checked all the fixes above:
Check for __init__ in metaclasses or __new__. If the class uses a custom metaclass or overrides __new__, the error might originate there instead of __init__.
Check for property setters. A @property setter must accept exactly one value argument:
class Config:
@property
def name(self):
return self._name
@name.setter
def name(self, value): # Must have 'value'
self._name = valueCheck for *args and **kwargs masking. If a base class accepts **kwargs and a subclass does not, arguments intended for the subclass might be swallowed:
class Base:
def __init__(self, **kwargs):
pass
class Child(Base):
def __init__(self, name): # 'name' must be passed positionally
super().__init__()
self.name = name
# This fails:
Child(name="Alice") # Works
Child() # TypeError: missing 'name'Check for circular imports. If a circular import causes a module to be partially loaded, classes or functions might be None or incomplete, leading to unexpected TypeError. See Fix: Python ImportError: circular import.
Check for Python version differences. Some functions changed their signatures between Python versions. For example, collections.OrderedDict.move_to_end() was added in Python 3.2. Check the Python docs for your version. If Python itself is not found, see Fix: python command not found.
Check for forgotten await on async functions. Calling an async def function without await returns a coroutine object, not the result. If you then try to pass that coroutine to something that expects the actual return value, the argument count looks right but the runtime call fails with the missing-argument variant when the coroutine is later awaited with the wrong args. See Fix: Python async/sync mix for the broader pattern.
Check for keyword-only argument requirements. A parameter declared after * in the signature is keyword-only: def func(a, *, b). Calling func(1, 2) raises TypeError: func() takes 1 positional argument but 2 were given and func(1) raises missing 1 required keyword-only argument: 'b'. Library authors increasingly use keyword-only arguments for clarity, especially in Python 3.10+.
Check for partial and partialmethod binding. functools.partial(func, arg) fixes arg as the first positional argument. If you later call the result, your supplied args shift right — and a method already bound to self then receives your arg as the second positional, leaving the next slot empty. Inspect with inspect.signature(partial_func) to see the post-binding signature.
Check for Pydantic and dataclass field changes. Adding a required field to a Pydantic model or dataclass without a default value breaks every existing instantiation. Use Field(default=...) or migrate existing call sites in the same commit.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: joblib Not Working — Parallel Backends, Memory Cache, and Pickling Errors
How to fix joblib errors — Parallel n_jobs slower than expected, Memory cache miss, backend loky vs threading vs multiprocessing, pickling lambda not supported, dump load file size, and pytest interference.
Fix: Marshmallow Not Working — Schema Errors, Load vs Dump, and Field Validation
How to fix Marshmallow errors — Schema not validated on dump, ValidationError messages format, unknown field handling, missing vs default, post_load object construction, and Marshmallow 3 to 4 migration.
Fix: Pipenv Not Working — Lock File Generation, Shell Activation, and Dependency Resolution
How to fix Pipenv errors — pipenv lock takes forever, Pipfile.lock not generated, shell activation broken, no virtualenv created, dependency conflict, and migration to uv or Poetry.
Fix: Copier Not Working — Template Updates, Question Conditions, and Migrations
How to fix Copier errors — copier.yml not found, conditional questions not appearing, update breaks generated project, migrations between versions, Jinja vs YAML escaping, and answers file conflict.