langchain-ai/langchain · error · ValueError

Field {obj} must have a name to be deprecated.

Error message

Field {obj} must have a name to be deprecated.

What it means

Raised inside the `deprecated` decorator when the object being deprecated is a Pydantic v1 `FieldInfo` (i.e. you decorated a `Field(...)` value from `pydantic.v1`) and no `name=` was passed to the decorator. A FieldInfo instance carries no reliable own name, so the decorator needs the field name to render the deprecation message and to rebuild the FieldInfo with an updated description.

Source

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

                    return wrapped(self, *args, **kwargs)

                obj.__init__ = functools.wraps(obj.__init__)(  # type: ignore[misc]
                    warn_if_direct_instance
                )
                # Set __deprecated__ for PEP 702 (IDE/type checker support)
                obj.__deprecated__ = _build_deprecation_message(  # type: ignore[attr-defined]
                    alternative=alternative,
                    alternative_import=alternative_import,
                )
                return obj

        elif _is_pydantic_v1_field_info(obj):
            wrapped = None
            if not _obj_type:
                _obj_type = "attribute"
            if not _name:
                msg = f"Field {obj} must have a name to be deprecated."
                raise ValueError(msg)
            old_doc = obj.description

            def finalize(_: Callable[..., Any], new_doc: str, /) -> T:
                from pydantic.v1.fields import FieldInfo as FieldInfoV1  # noqa: PLC0415

                return cast(
                    "T",
                    FieldInfoV1(
                        default=obj.default,
                        default_factory=obj.default_factory,
                        description=new_doc,
                        alias=obj.alias,
                        exclude=obj.exclude,
                    ),
                )

        elif isinstance(obj, FieldInfo):
            wrapped = None

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Pass the field name to the decorator: `deprecated("0.3", name="my_field")`.
  2. If you intended to deprecate the whole model or method rather than one field, decorate that object instead — it knows its own name.

Example fix

# before
class MyModel(BaseModelV1):
    old_attr: int = deprecated("0.3")(Field(default=0))

# after
class MyModel(BaseModelV1):
    old_attr: int = deprecated("0.3", name="old_attr")(Field(default=0))
Defensive patterns

Strategy: validation

Validate before calling

def deprecate_v1_field(since: str, name: str | None, field) -> Any:
    if not name:
        raise ValueError("Field deprecation requires name=")
    return deprecated(since, name=name)(field)

Type guard

from pydantic.v1.fields import FieldInfo as FieldInfoV1

def is_v1_field_info(obj: object) -> bool:
    return isinstance(obj, FieldInfoV1)

Prevention

When it happens

Trigger: `x: int = deprecated("0.3")(Field(default=1, description="..."))` where the `Field` comes from `pydantic.v1` (or the pydantic.v1 compatibility shim) and the decorator call omits `name=`. The check `if not _name` fires at class-definition/import time.

Common situations: Migrating a legacy langchain model that still uses pydantic.v1 fields; the author decorates a Field with `@deprecated(since=...)` the way they would a function and forgets that fields need an explicit name. Also occurs when deprecating an attribute where the surrounding class refactor removed the name argument.

Related errors


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