langchain-ai/langchain · error · ValueError
Cannot specify both alternative and alternative_import
Error message
Cannot specify both alternative and alternative_import
What it means
Raised by `_validate_deprecation_params` when a `@deprecated` / `warn_deprecation` call supplies both `alternative` (a free-text replacement description) and `alternative_import` (a dotted import path). The two are mutually exclusive ways to tell users what to use instead; `alternative_import` auto-generates the guidance, so both cannot be given.
Source
Thrown at libs/core/langchain_core/_api/deprecation.py:110
# scope emits a `UserWarning` on Python 3.14+; v1 `FieldInfo` support is handled
# at runtime via `_is_pydantic_v1_field_info`.
T = TypeVar("T", bound=type | Callable[..., Any] | Any)
def _validate_deprecation_params(
removal: str,
alternative: str,
alternative_import: str,
*,
pending: bool,
) -> None:
"""Validate the deprecation parameters."""
if pending and removal:
msg = "A pending deprecation cannot have a scheduled removal"
raise ValueError(msg)
if alternative and alternative_import:
msg = "Cannot specify both alternative and alternative_import"
raise ValueError(msg)
if alternative_import and "." not in alternative_import:
msg = (
"alternative_import must be a fully qualified module path. Got "
f" {alternative_import}"
)
raise ValueError(msg)
def deprecated(
since: str,
*,
message: str = "",
name: str = "",
alternative: str = "",
alternative_import: str = "",
pending: bool = False,
obj_type: str = "",View on GitHub (pinned to e32fa9a52e)
Solutions
- If the replacement is importable, keep only `alternative_import="pkg.module.attr"` and drop `alternative`.
- If the guidance needs prose (e.g. multi-step migration), keep only `alternative=` and drop `alternative_import`.
Example fix
# before
@deprecated("0.3", alternative="Use new_fn", alternative_import="mymod.new_fn")
def old_fn(): ...
# after
@deprecated("0.3", alternative_import="mymod.new_fn")
def old_fn(): ... Defensive patterns
Strategy: validation
Validate before calling
def validate_alternative(alternative: str, alternative_import: str) -> None:
if alternative and alternative_import:
raise ConfigError("pass alternative OR alternative_import, not both") Prevention
- Pick one convention per codebase (prefer alternative_import when the replacement is importable) and enforce it in review.
- Add a unit test that smoke-imports every module declaring deprecations — misconfiguration fails at import time.
When it happens
Trigger: Any decorator or call like `@deprecated(since="0.3", alternative="Use `x.y.new_api`", alternative_import="x.y.new_api")`. Validation runs at decoration/import time and fails immediately with ValueError.
Common situations: Migrating an existing deprecation that used a prose `alternative` over to the newer `alternative_import` style and leaving the old kwarg in place, or copy-pasting a deprecation block and appending rather than replacing the alternative field.
Related errors
- A pending deprecation cannot have a scheduled removal
- alternative_import must be a fully qualified module path. Go
- Field {obj} must have a name to be deprecated.
- {f.__name__}() got multiple values for argument {new!r}
- module '{package!r}' has no attribute {attr_name!r}
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/2d6aaad00542f067.
Report an issue: GitHub.