{"id":"040d7ddbaa107b31","repo":"sqlalchemy/sqlalchemy","slug":"methname-got-an-unexpected-keyword-argument-k","errorCode":null,"errorMessage":"{methname} got an unexpected keyword argument '{k}'","messagePattern":"(.+?) got an unexpected keyword argument '(.+?)'","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/sqlalchemy/sql/_typing.py","lineNumber":415,"sourceCode":"\ndef is_has_clause_element(s: object) -> TypeGuard[_HasClauseElement[Any]]:\n    return hasattr(s, \"__clause_element__\")\n\n\ndef is_insert_update(c: ClauseElement) -> TypeGuard[ValuesBase]:\n    return c.is_dml and (c.is_insert or c.is_update)  # type: ignore[attr-defined]  # noqa: E501\n\n\ndef _no_kw() -> exc.ArgumentError:\n    return exc.ArgumentError(\n        \"Additional keyword arguments are not accepted by this \"\n        \"function/method.  The presence of **kw is for pep-484 typing purposes\"\n    )\n\n\ndef _unexpected_kw(methname: str, kw: Dict[str, Any]) -> NoReturn:\n    k = list(kw)[0]\n    raise TypeError(f\"{methname} got an unexpected keyword argument '{k}'\")\n\n\n@overload\ndef Nullable(\n    val: \"SQLCoreOperations[_T]\",\n) -> \"SQLCoreOperations[Optional[_T]]\": ...\n\n\n@overload\ndef Nullable(\n    val: roles.ExpressionElementRole[_T],\n) -> roles.ExpressionElementRole[Optional[_T]]: ...\n\n\n@overload\ndef Nullable(val: Type[_T]) -> Type[Optional[_T]]: ...\n\n","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/sqlalchemy/sqlalchemy/blob/d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff/lib/sqlalchemy/sql/_typing.py#L397-L433","documentation":"Raised by the SQLAlchemy internal helper _unexpected_kw() in sql/_typing.py, which is a thin shim that converts an unexpected leftover **kw dict into a standard Python TypeError. Many SQLAlchemy public/semi-public APIs accept **kw purely for PEP-484 typing/static-analysis reasons but do not actually consume arbitrary keyword arguments at runtime; if any kwargs remain unprocessed, this helper raises. It mirrors the behavior of Python's native 'unexpected keyword argument' error for functions whose signatures use a catch-all **kw.","triggerScenarios":"Calling a SQLAlchemy API that uses a typing-only **kw parameter and passing a keyword it does not actually accept, e.g. passing an unknown kwarg to a method that lists **kw for type overloads. The helper is invoked internally when SQLAlchemy detects leftover kwargs that should have been consumed, e.g. through helper code paths that forward kwargs and then call _unexpected_kw(methname, remaining_kw).","commonSituations":"Migrating code where method signatures changed between minor SQLAlchemy releases and a previously-tolerated kwarg is now rejected; passing dialect-specific or deprecated kwargs to core methods; static type stubs suggesting an argument that the runtime does not honor; typos in keyword names passed to ORM/Core builder methods.","solutions":["Check the exact keyword name reported ('{k}') for a typo against the target method's documented signature.","Remove the unsupported keyword argument, or move it to a location that accepts it (e.g. dialect_kwargs via the <dialect>_<arg> naming convention).","If relying on a deprecated argument, consult the SQLAlchemy changelog/migration notes for the installed version and switch to the replacement.","Verify you are not passing generic **kwargs through from your own wrapper that were intended for a different function."],"exampleFix":"// before\nstmt = select(User).options(some_loader(User.addresses, invalid_kw=True))\n\n// after\nstmt = select(User).options(some_loader(User.addresses))","handlingStrategy":"type-guard","validationCode":"import inspect\n\ndef validate_kwargs_accepted(func, *args, **kwargs):\n    \"\"\"Call before invoking func(**kw) to guarantee no 'unexpected keyword\n    argument' TypeError is raised by SQLAlchemy's _unexpected_kw guard.\"\"\"\n    sig = inspect.signature(func)\n    accepts_var_kw = any(\n        p.kind is inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()\n    )\n    if accepts_var_kw:\n        return  # cannot statically reject; SQLAlchemy will reject unknown kw\n    allowed = {\n        name for name, p in sig.parameters.items()\n        if p.kind in (p.POSITIONAL_OR_KEYWORD, p.KEYWORD_ONLY)\n    }\n    unknown = set(kwargs) - allowed\n    if unknown:\n        raise TypeError(\n            f\"{func.__qualname__} does not accept kwargs: {sorted(unknown)}\"\n        )","typeGuard":"import inspect\n\ndef accepts_keyword(func, key: str) -> bool:\n    \"\"\"Type-guard: True if func genuinely accepts keyword `key`.\"\"\"\n    try:\n        sig = inspect.signature(func)\n    except (TypeError, ValueError):\n        return True  # builtin/C-funcs: assume permissive\n    params = sig.parameters\n    if any(p.kind is p.VAR_KEYWORD for p in params.values()):\n        # SQLAlchemy functions with **kw often reject via _no_kw/_unexpected_kw,\n        # so treat VAR_KEYWORD as NON-permissive here.\n        return False\n    return key in params and params[key].kind in (\n        params[key].POSITIONAL_OR_KEYWORD, params[key].KEYWORD_ONLY\n    )","tryCatchPattern":"try:\n    result = sa_func(known_arg=1, bogus_arg=2)\nexcept TypeError as e:\n    if \"unexpected keyword argument\" in str(e):\n        # strip the offending kwarg and retry, or surface a clear error\n        raise TypeError(f\"Unsupported kwarg passed to SQLAlchemy API: {e}\") from e\n    raise","preventionTips":["Treat SQLAlchemy **kw parameters shown in signatures as type-check-only stubs: they reject at runtime via _no_kw/_unexpected_kw, so do not forward arbitrary kwargs into them.","When wrapping SQLAlchemy functions, filter kwargs through inspect.signature rather than passing **kwargs blindly.","Keep mypy strict and let the typed SQLAlchemy 2.0 stubs reject unknown kwargs at static-analysis time."],"tags":["typing","kwargs","internal-api","sqlalchemy-2"],"analyzedSha":"d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff","analyzedAt":"2026-08-01T17:20:52.075Z","schemaVersion":2}