langchain-ai/langchain · error · TypeError

{f.__name__}() got multiple values for argument {new!r}

Error message

{f.__name__}() got multiple values for argument {new!r}

What it means

Raised by the `rename_parameter("since", "old", "new")` decorator's wrapper when the caller passes BOTH the old and the new parameter name as keyword arguments in one call. The wrapper cannot map both onto a single parameter, so instead of silently dropping one it raises TypeError, mirroring Python's own 'got multiple values' semantics.

Source

Thrown at libs/core/langchain_core/_api/deprecation.py:623

        old: The old parameter name.
        new: The new parameter name.

    Returns:
        A decorator indicating that a parameter was renamed.

    Example:
        ```python
        @_api.rename_parameter("3.1", "bad_name", "good_name")
        def func(good_name): ...
        ```
    """

    def decorator(f: Callable[_P, _R]) -> Callable[_P, _R]:
        @functools.wraps(f)
        def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
            if new in kwargs and old in kwargs:
                msg = f"{f.__name__}() got multiple values for argument {new!r}"
                raise TypeError(msg)
            if old in kwargs:
                warn_deprecated(
                    since,
                    removal=removal,
                    message=f"The parameter `{old}` of `{f.__name__}` was "
                    f"deprecated in {since} and will be removed "
                    f"in {removal} Use `{new}` instead.",
                )
                kwargs[new] = kwargs.pop(old)
            return f(*args, **kwargs)

        return wrapper

    return decorator

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Delete the old-named key at the source: update the wrapper/defaults dict that still passes `bad_name` so only `good_name` reaches the call.
  2. If kwargs are merged dynamically, pop the deprecated alias before calling: `merged.pop('bad_name', None)` once you've confirmed `good_name` is present (or keep only whichever key is set).
  3. Enable `-W error::DeprecationWarning` in tests so the remaining old-name call sites surface before they collide with new-name callers.

Example fix

# before
func(bad_name=1, good_name=2)  # TypeError

# after
func(good_name=2)
Defensive patterns

Strategy: validation

Validate before calling

def strip_renamed_kwargs(
    kwargs: dict[str, object], old: str, new: str
) -> dict[str, object]:
    """Keep at most one of old/new; prefer new when both are present by policy."""
    kwargs = dict(kwargs)
    if new in kwargs:
        kwargs.pop(old, None)  # or raise, if old must be authoritative
    elif old in kwargs:
        kwargs[new] = kwargs.pop(old)
    return kwargs

Try / catch

try:
    func(good_name=1)
except TypeError as e:
    if 'multiple values' in str(e):
        # resolve the duplicate kwarg source, then retry with a single name
        ...
    raise

Prevention

When it happens

Trigger: Given `@rename_parameter("3.1", "bad_name", "good_name")` on `def func(good_name)`, calling `func(bad_name=1, good_name=2)` raises `TypeError: func() got multiple values for argument 'good_name'`. Only triggers via keywords; a single old-named keyword is still accepted (with a deprecation warning) and rewritten to the new name.

Common situations: Call sites mid-migration where one caller updated code to the new name while another layer (a wrapper, config-to-kwargs bridge, or merged dict) still injects the old name. Common in orchestration code that builds kwargs from multiple sources, e.g. `{**user_kwargs, **defaults}` where defaults still use the deprecated name.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/bcacac5a594f1023. Report an issue: GitHub.