{"record":{"id":"0bdf060b68eaae76","repo":"langchain-ai/langchain","slug":"class-self-class-has-a-deprecated-attribute","errorCode":null,"errorMessage":"Class {self.__class__} has a deprecated attribute {attr}. Please use the corresponding classmethod instead.","messagePattern":"Class (.+?) has a deprecated attribute (.+?)\\. Please use the corresponding classmethod instead\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/load/serializable.py","lineNumber":271,"sourceCode":"        for cls in [None, *self.__class__.mro()]:\n            # Once we get to Serializable, we're done\n            if cls is Serializable:\n                break\n\n            if cls:\n                deprecated_attributes = [\n                    \"lc_namespace\",\n                    \"lc_serializable\",\n                ]\n\n                for attr in deprecated_attributes:\n                    if hasattr(cls, attr):\n                        msg = (\n                            f\"Class {self.__class__} has a deprecated \"\n                            f\"attribute {attr}. Please use the corresponding \"\n                            f\"classmethod instead.\"\n                        )\n                        raise ValueError(msg)\n\n            # Get a reference to self bound to each class in the MRO\n            this = cast(\"Serializable\", self if cls is None else super(cls, self))\n\n            secrets.update(this.lc_secrets)\n            # Now also add the aliases for the secrets\n            # This ensures known secret aliases are hidden.\n            # Note: this does NOT hide any other extra kwargs\n            # that are not present in the fields.\n            for key in list(secrets):\n                value = secrets[key]\n                if (key in model_fields) and (\n                    alias := model_fields[key].alias\n                ) is not None:\n                    secrets[alias] = value\n            lc_kwargs.update(this.lc_attributes)\n\n        # include all secrets, even if not specified in kwargs","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/load/serializable.py#L253-L289","documentation":"Runtime guard in Serializable.to_json: a class in the MRO still declares a deprecated class/instance attribute `lc_namespace` or `lc_serializable` instead of the classmethod replacements (lc_namespace() became a classmethod; lc_serializable was removed in favor of always-on serialization via to_json). The check fires on every to_json call when any inherited class re-introduces these attributes.","triggerScenarios":"A custom class defines lc_namespace = ['my_pkg'] as a plain attribute or lc_serializable = True for old-style opt-in serialization, then any dumps()/dumpd()/to_json() on it (or on a chain containing it) raises. Copying serialization code from LangChain pre-0.1 examples triggers this.","commonSituations":"Upgrading old integrations that used the pre-core serialization API; AI/tutorial code copied from old docs; custom Serializable subclasses that never migrated off attribute-style declarations.","solutions":["Replace lc_namespace attribute with the classmethod: @classmethod def lc_namespace(cls) -> list[str]","Delete lc_serializable entirely — subclasses of Serializable are serializable by default","Grep your custom classes for 'lc_namespace =' and 'lc_serializable' and migrate each hit"],"exampleFix":"# before\nclass MyChain(Serializable):\n    lc_namespace = ['my_pkg']\n    lc_serializable = True\n# after\nclass MyChain(Serializable):\n    @classmethod\n    def lc_namespace(cls) -> list[str]:\n        return ['my_pkg']","handlingStrategy":"type-guard","validationCode":"from langchain_core.load.serializable import Serializable\ndef check_serializable_class(cls: type) -> None:\n    for bad in ('lc_namespace', 'lc_serializable'):\n        assert bad not in cls.__dict__ and bad not in {k for b in cls.__mro__ for k in vars(b)}, f'{cls} declares deprecated attribute {bad}'","typeGuard":"def uses_modern_serialization(cls: type) -> bool:\n    return all(not hasattr(b, 'lc_namespace') or 'lc_namespace' not in vars(b) or isinstance(vars(b).get('lc_namespace'), classmethod) for b in cls.__mro__) and not any('lc_serializable' in vars(b) for b in cls.__mro__)","tryCatchPattern":"try:\n    dumps(obj)\nexcept ValueError as e:\n    if 'deprecated attribute' in str(e):\n        # remove/convert the attribute on the offending class, then retry\n        raise\n    raise","preventionTips":["After upgrading langchain-core, grep custom classes for lc_namespace = and lc_serializable","Declare namespaces via the lc_namespace classmethod only","Drop lc_serializable — Serializable subclasses serialize automatically"],"tags":["serialization","migration","deprecated-api","serializable"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}