TypeError: takes 1 positional argument but 2 were given
1 · The lesson
readWhat this error means
A function received more positional arguments than its def line has room for. Python counts every positional value that arrives — including the one it slips in for you — and the count came out higher than the function accepts.
The numbers in the message are the whole story. If they look off by one from what you typed, the extra one is self.
When you see it
Traceback (most recent call last): File "main.py", line 9, in <module> cart.add("earl grey") ~~~~~~~~^^^^^^^^^^^^^ TypeError: Cart.add() takes 1 positional argument but 2 were given
You passed one argument. Python says two. That gap is the classic missing self.
Why it happens
When you call cart.add("earl grey"), Python rewrites it as Cart.add(cart, "earl grey"). The object goes in first, always. So a method defined as def add(item): has room for exactly one value, and the object has already taken it.
class Cart: def __init__(self): self.items = [] def add(item): # forgot self self.items.append(item) cart = Cart() cart.add("earl grey") # TypeError: Cart.add() takes 1 positional argument but 2 were given
The other two causes are less sneaky:
- You really did pass too many. A function that used to take three arguments was trimmed to two, and one caller still sends three.
- The parameter is keyword-only. Anything after a bare
*in thedefline must be passed by name. Passing it positionally counts as one positional too many.
How to fix it
Add self as the first parameter of every instance method. This fixes the large majority of cases:
class Cart: def __init__(self): self.items = [] def add(self, item): self.items.append(item) cart = Cart() cart.add("earl grey") cart.add("oat milk") print(cart.items) # ['earl grey', 'oat milk']
If the method genuinely doesn't need the object, say so with @staticmethod instead of adding a self you never use:
class Price: @staticmethod def pence(pounds): return round(pounds * 100) print(Price.pence(4.99)) # 499 print(Price().pence(4.99)) # 499 — works on an instance too
For keyword-only parameters, pass them by name. The * is there on purpose, usually to stop someone mixing up two strings:
def send_invoice(invoice_id, *, copy_to=None): target = f" (copy to {copy_to})" if copy_to else "" print(f"Sent {invoice_id}{target}") send_invoice("INV-1042", copy_to="grace@example.com") # Sent INV-1042 (copy to grace@example.com) # send_invoice("INV-1042", "grace@example.com") # takes 1 positional argument but 2 were given
For a genuine extra argument, check the signature you're actually calling — help(func) or inspect.signature(func) — rather than the one you remember:
import inspect def ship(order_id, courier): return f"{order_id} via {courier}" print(inspect.signature(ship)) # (order_id, courier)
When you'd actually see this in real code
- Writing your first class and leaving
selfout of a method. Nearly everyone does it once. threading.Thread(target=process, args=("orders.csv")). Without a trailing comma that is a string, not a tuple, so each of its 10 characters becomes an argument:process() takes 1 positional argument but 10 were given. Writeargs=("orders.csv",).- Moving a module-level helper into a class by indenting it, and not adding
self. - A callback that a framework calls with an extra
eventorrequestargument your function doesn't declare. - Upgrading pandas to 2.x, where most optional parameters became keyword-only. Old code like
df.drop("notes", 1)now fails withDataFrame.drop() takes from 1 to 2 positional arguments but 3 were given; writedf.drop(columns="notes").
Related errors
- TypeError: missing 1 required positional argument — the opposite count: too few arguments.
- TypeError: got an unexpected keyword argument — a name the function doesn't recognise.
- NameError: name 'X' is not defined — what you get next if you add
selfto thedefbut still writeitemsinstead ofself.items.
See Also
- All Python errors — the full index, by type and by when it happens.
- Classes and objects (tutorial)
- Functions (tutorial)
- Multiprocessing and threads
Found this useful? Share it with a friend who’s learning Python.