{"record":{"id":"2d6aaad00542f067","repo":"langchain-ai/langchain","slug":"cannot-specify-both-alternative-and-alternative-im","errorCode":null,"errorMessage":"Cannot specify both alternative and alternative_import","messagePattern":"Cannot specify both alternative and alternative_import","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/_api/deprecation.py","lineNumber":110,"sourceCode":"# scope emits a `UserWarning` on Python 3.14+; v1 `FieldInfo` support is handled\n# at runtime via `_is_pydantic_v1_field_info`.\nT = TypeVar(\"T\", bound=type | Callable[..., Any] | Any)\n\n\ndef _validate_deprecation_params(\n    removal: str,\n    alternative: str,\n    alternative_import: str,\n    *,\n    pending: bool,\n) -> None:\n    \"\"\"Validate the deprecation parameters.\"\"\"\n    if pending and removal:\n        msg = \"A pending deprecation cannot have a scheduled removal\"\n        raise ValueError(msg)\n    if alternative and alternative_import:\n        msg = \"Cannot specify both alternative and alternative_import\"\n        raise ValueError(msg)\n\n    if alternative_import and \".\" not in alternative_import:\n        msg = (\n            \"alternative_import must be a fully qualified module path. Got \"\n            f\" {alternative_import}\"\n        )\n        raise ValueError(msg)\n\n\ndef deprecated(\n    since: str,\n    *,\n    message: str = \"\",\n    name: str = \"\",\n    alternative: str = \"\",\n    alternative_import: str = \"\",\n    pending: bool = False,\n    obj_type: str = \"\",","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/_api/deprecation.py#L92-L128","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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`."],"exampleFix":"# before\n@deprecated(\"0.3\", alternative=\"Use new_fn\", alternative_import=\"mymod.new_fn\")\ndef old_fn(): ...\n\n# after\n@deprecated(\"0.3\", alternative_import=\"mymod.new_fn\")\ndef old_fn(): ...","handlingStrategy":"validation","validationCode":"def validate_alternative(alternative: str, alternative_import: str) -> None:\n    if alternative and alternative_import:\n        raise ConfigError(\"pass alternative OR alternative_import, not both\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["deprecation","langchain-core","api-misuse"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}