{"record":{"id":"0ed00d2b1bd67406","repo":"FoundationAgents/MetaGPT","slug":"missing-module-class-name-field","errorCode":null,"errorMessage":"Missing __module_class_name field","messagePattern":"Missing __module_class_name field","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/base/base_serialization.py","lineNumber":54,"sourceCode":"        # it is a dict so make sure to remove the __module_class_name\n        # because we don't allow extra keywords but want to ensure\n        # e.g Cat.model_validate(cat.model_dump()) works\n        class_full_name = value.pop(\"__module_class_name\", None)\n\n        # if it's not the polymorphic base we construct via default handler\n        if not cls.__is_polymorphic_base:\n            if class_full_name is None:\n                return handler(value)\n            elif str(cls) == f\"<class '{class_full_name}'>\":\n                return handler(value)\n            else:\n                # f\"Trying to instantiate {class_full_name} but this is not the polymorphic base class\")\n                pass\n\n        # otherwise we lookup the correct polymorphic type and construct that\n        # instead\n        if class_full_name is None:\n            raise ValueError(\"Missing __module_class_name field\")\n\n        class_type = cls.__subclasses_map__.get(class_full_name, None)\n\n        if class_type is None:\n            # TODO could try dynamic import\n            raise TypeError(f\"Trying to instantiate {class_full_name}, which has not yet been defined!\")\n\n        return class_type(**value)\n\n    def __init_subclass__(cls, is_polymorphic_base: bool = False, **kwargs):\n        cls.__is_polymorphic_base = is_polymorphic_base\n        cls.__subclasses_map__[f\"{cls.__module__}.{cls.__qualname__}\"] = cls\n        super().__init_subclass__(**kwargs)\n","sourceCodeStart":36,"sourceCodeEnd":68,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/base/base_serialization.py#L36-L68","documentation":"MetaGPT's polymorphic serialization base (metagpt/base/base_serialization.py) deserializes objects by reading the __module_class_name marker from the serialized dict to pick the right subclass. If that field is absent while the target class is a polymorphic base (or the class does not match), ValidationError/ValueError 'Missing __module_class_name field' is raised because there is no way to know which concrete subclass to instantiate.","triggerScenarios":"Calling BaseModel.serialization_module_from_dict (or APIs that use it, e.g. context/agent deserialization) on a dict that was produced by plain json.loads of stored JSON where __module_class_name was stripped, or by manually constructing a dict of field values without the marker.","commonSituations":"Persisting serialized objects after post-processing that removes underscore-prefixed keys; schema drift between MetaGPT versions that renamed the marker field; hand-crafted dicts passed to deserializing loaders.","solutions":["Serialize with the framework's own serializer so __module_class_name is included, and do not strip underscore keys before deserialization.","If you must patch a dict, re-add the marker: value['__module_class_name'] = 'metagpt.module.ClassName' before deserializing.","Deserialize against the concrete subclass directly (class_type(**value)) when you know the type, bypassing the polymorphic path."],"exampleFix":"# before\nd = json.loads(saved_json)          # __module_class_name lost\nobj = MyClass.serialization_module_from_dict(d)  # ValueError\n\n# after\nd = json.loads(saved_json)\nd.setdefault('__module_class_name', 'metagpt.module.MyClass')\nobj = MyClass.serialization_module_from_dict(d)","handlingStrategy":"validation","validationCode":"if isinstance(value, dict) and '__module_class_name' not in value:\n    value['__module_class_name'] = f'{cls.__module__}.{cls.__qualname__}'\nobj = cls.serialization_module_from_dict(value)","typeGuard":"def has_class_marker(d: dict) -> bool:\n    return isinstance(d, dict) and isinstance(d.get('__module_class_name'), str) and d['__module_class_name']","tryCatchPattern":"try:\n    obj = cls.serialization_module_from_dict(value)\nexcept ValueError:\n    value = dict(value)\n    value['__module_class_name'] = 'metagpt.module.ExpectedClass'\n    obj = cls.serialization_module_from_dict(value)","preventionTips":["Only round-trip through the framework's serializer.","Never strip underscore-prefixed keys from serialized payloads.","Add schema assertions in tests that serialized dicts retain the class marker."],"tags":["serialization","deserialization","polymorphic","schema"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}