pydantic/pydantic · error · TypeError
positional-only argument{plural} passed as keyword argument{
Error message
positional-only argument{plural} passed as keyword argument{plural}: {keys} What it means
Raised at call time by the check_positional_only validator when a @validate_arguments-decorated function declares positional-only parameters (using / in the signature, or C-style positional-only) and the caller passes one of them as a keyword argument. build_values detects such keys and stores them in V_POSITIONAL_ONLY_NAME; the validator then raises.
Source
Thrown at pydantic/v1/decorator.py:250
raise TypeError(f'{pos_args} positional arguments expected but {pos_args + len(v)} given')
@validator(self.v_kwargs_name, check_fields=False, allow_reuse=True)
def check_kwargs(cls, v: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
if takes_kwargs or v is None:
return v
plural = '' if len(v) == 1 else 's'
keys = ', '.join(map(repr, v.keys()))
raise TypeError(f'unexpected keyword argument{plural}: {keys}')
@validator(V_POSITIONAL_ONLY_NAME, check_fields=False, allow_reuse=True)
def check_positional_only(cls, v: Optional[List[str]]) -> None:
if v is None:
return
plural = '' if len(v) == 1 else 's'
keys = ', '.join(map(repr, v))
raise TypeError(f'positional-only argument{plural} passed as keyword argument{plural}: {keys}')
@validator(V_DUPLICATE_KWARGS, check_fields=False, allow_reuse=True)
def check_duplicate_kwargs(cls, v: Optional[List[str]]) -> None:
if v is None:
return
plural = '' if len(v) == 1 else 's'
keys = ', '.join(map(repr, v))
raise TypeError(f'multiple values for argument{plural}: {keys}')
class Config(CustomConfig):
extra = getattr(CustomConfig, 'extra', Extra.forbid)
self.model = create_model(to_camel(self.raw_function.__name__), __base__=DecoratorBaseModel, **fields)
View on GitHub (pinned to 2e5f0e2b42)
Solutions
- Pass positional-only arguments positionally, not by keyword.
- If keyword usage is required, remove the '/' positional-only marker from the signature.
Example fix
// before @validate_arguments def f(a: int, b: int, /): ... f(1, b=2) # raises: positional-only argument passed as keyword: 'b' # after f(1, 2) # pass positionally
Defensive patterns
Strategy: validation
Validate before calling
import inspect
def _enforce_positional_only(func, args, kwargs):
params = inspect.signature(func).parameters
pos_only = {n for n, p in params.items() if p.kind == p.POSITIONAL_ONLY}
clash = set(kwargs) & pos_only
if clash:
raise TypeError(f'pass these positionally, not by keyword: {clash}') Type guard
import inspect
def no_positional_only_as_keyword(func, kwargs) -> bool:
params = inspect.signature(func).parameters
pos_only = {n for n, p in params.items() if p.kind == p.POSITIONAL_ONLY}
return set(kwargs).isdisjoint(pos_only) Try / catch
try:
result = wrapped_fn(*args, **kwargs)
except TypeError as e:
if 'positional-only' in str(e):
# move clashing kwargs into positional order
... Prevention
- Document positional-only params clearly in docstrings.
- Avoid forwarding external kwargs into functions with positional-only params.
- Consider dropping the '/' marker if keyword usage is common.
When it happens
Trigger: A function with positional-only params (def f(a, b, /)) decorated with @validate_arguments, called as f(1, b=2) — passing a positional-only arg 'b' by keyword.
Common situations: Migrating a function to positional-only syntax with /; calling a library function whose signature was tightened to positional-only; forwarding kwargs that include a positional-only name.
Related errors
- {pos_args} positional arguments expected but {pos_args + len
- unexpected keyword argument{plural}: {keys}
- multiple values for argument{plural}: {keys}
- {pos_args} positional arguments expected but {pos_args + len
- positional-only argument{plural} passed as keyword argument{
AI-assisted analysis of pydantic/pydantic@2e5f0e2b42 (2026-08-04).
Data as JSON: /data/errors/b4601ed8362548eb.json.
Report an issue: GitHub.