openai/openai-python · error · TypeError

{func.__name__}() takes {len(positional)} argument(s) but {l

Error message

{func.__name__}() takes {len(positional)} argument(s) but {len(args)} were given

What it means

The SDK uses a @required_args decorator on resource methods to reproduce Python's native 'takes N arguments but M were given' error for overloads with optional positional parameters. This TypeError fires when more positional arguments are passed than the method declares, i.e. the call site is treating the method as if it had extra positional slots (often a tuple splat or a copied call from another method's signature).

Source

Thrown at src/openai/_utils/_utils.py:271

        params = inspect.signature(func).parameters
        positional = [
            name
            for name, param in params.items()
            if param.kind
            in {
                param.POSITIONAL_ONLY,
                param.POSITIONAL_OR_KEYWORD,
            }
        ]

        @functools.wraps(func)
        def wrapper(*args: object, **kwargs: object) -> object:
            given_params: set[str] = set()
            for i, _ in enumerate(args):
                try:
                    given_params.add(positional[i])
                except IndexError:
                    raise TypeError(
                        f"{func.__name__}() takes {len(positional)} argument(s) but {len(args)} were given"
                    ) from None

            for key in kwargs.keys():
                given_params.add(key)

            for variant in variants:
                matches = all((param in given_params for param in variant))
                if matches:
                    break
            else:  # no break
                if len(variants) > 1:
                    variations = human_join(
                        ["(" + human_join([quote(arg) for arg in variant], final="and") + ")" for variant in variants]
                    )
                    msg = f"Missing required arguments; Expected either {variations} arguments to be given"
                else:
                    assert len(variants) > 0

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Pass parameters as keyword arguments: client.things.get(thing_id="...")
  2. Check the method signature in the installed SDK version (help(client.things.get)) and fix the call arity
  3. In wrappers, forward **kwargs only, not *args, so arity is checked by keywords
  4. Pin the SDK version in lockfiles while fixing call sites after an upgrade

Example fix

# before
client.fine_tuning.jobs.retrieve(*params_tuple)  # tuple too long

# after
client.fine_tuning.jobs.retrieve(job_id=params_tuple[0])
Defensive patterns

Strategy: validation

Validate before calling

import inspect
sig = inspect.signature(method)
positional = [p for p in sig.parameters.values() if p.kind in (p.POSITIONAL_ONLY, p.POSITIONAL_OR_KEYWORD)]
assert len(args) <= len(positional)

Type guard

def arity_ok(method, args: tuple) -> bool:
    import inspect
    try:
        inspect.signature(method).bind(*args)
        return True
    except TypeError:
        return False

Try / catch

try:
    method(*args)
except TypeError as e:
    if "were given" in str(e): fix_arity_and_retry()

Prevention

When it happens

Trigger: Calling an SDK resource method with too many positional args, e.g. client.things.get("a", "b", "c") for a method taking two; programmatically forwarding *args from a wrapper that appends extras; version upgrades that removed or merged positional parameters.

Common situations: Generic wrappers that forward *args to SDK methods whose signatures shrank between versions; copy-pasted calls between similar endpoints; splatting tuples of the wrong length.

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/9ad8b05b9765c0b4. Report an issue: GitHub.