{"record":{"id":"3f66d8cea460ca20","repo":"deepset-ai/haystack","slug":"missing-type-in-serialization-data","errorCode":null,"errorMessage":"Missing 'type' in serialization data","messagePattern":"Missing 'type' in serialization data","errorType":"exception","errorClass":"DeserializationError","httpStatus":null,"severity":"error","filePath":"haystack/core/serialization.py","lineNumber":299,"sourceCode":"    qualified class name are automatically detected and deserialized if the class has a\n    `from_dict()` method.\n\n    :param cls:\n        The class to be used for deserialization.\n    :param data:\n        The serialized data.\n    :returns:\n        The deserialized object.\n\n    :raises DeserializationError:\n        If the `type` field in `data` is missing or it doesn't match the type of `cls`.\n    \"\"\"\n    # Copy so that replacing serialized sub-objects (Secret/ComponentDevice/nested components) with their\n    # deserialized instances below does not mutate the caller's ``data`` dict in place. Without this, a second\n    # deserialization of the same dict would receive already-parsed objects instead of their serialized form.\n    init_params = dict(data.get(\"init_parameters\", {}))\n    if \"type\" not in data:\n        raise DeserializationError(\"Missing 'type' in serialization data\")\n    if data[\"type\"] != generate_qualified_class_name(cls):\n        raise DeserializationError(f\"Class '{data['type']}' can't be deserialized as '{cls.__name__}'\")\n\n    valid_init_param_names = _init_parameter_names(cls)\n\n    # Automatically detect and deserialize objects with from_dict methods\n    for key, value in init_params.items():\n        if isinstance(value, dict) and \"type\" in value:\n            type_value = value.get(\"type\")\n            # Special handling for Secret (type == \"env_var\")\n            if type_value == \"env_var\":\n                init_params[key] = Secret.from_dict(value)\n            # Special handling for ComponentDevice (type == \"single\" or \"multiple\")\n            elif _is_serialized_component_device(value):\n                init_params[key] = ComponentDevice.from_dict(value)\n            # If type looks like a fully qualified class name, try to import it and deserialize\n            elif isinstance(type_value, str) and \".\" in type_value:\n                # Reject before importing if the parent class does not accept this parameter.","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/core/serialization.py#L281-L317","documentation":"default_from_dict() requires the serialized dict to include a 'type' key identifying the class to instantiate. When the key is absent, Haystack cannot determine which component class to build and raises DeserializationError. Every Haystack serialized object embeds its fully-qualified class name under 'type'.","triggerScenarios":"Calling component.from_dict({}) or Pipeline.loads() on hand-written or truncated YAML/JSON where the top-level mapping or an init_parameters entry lacks 'type'.","commonSituations":"Hand-editing pipeline YAML and deleting the type line; external tools generating pipeline configs; loading files produced by a different format or older tooling.","solutions":["Add the missing 'type' key with the fully-qualified class name, e.g. 'haystack.components.retrievers.in_memory.InMemoryEmbeddingRetriever'.","Re-export the pipeline from the working environment with pipeline.dumps() and use that output.","Validate the YAML/JSON structure before loading.","Check you are loading the correct file (not a fragment)."],"exampleFix":"// before\n{\"init_parameters\": {\"sparse_embedding_model\": \"bm25\"}}\n\n// after\n{\"type\": \"haystack.components.retrievers.in_memory.InMemoryEmbeddingRetriever\", \"init_parameters\": {\"sparse_embedding_model\": \"bm25\"}}","handlingStrategy":"validation","validationCode":"def ensure_typed(obj: dict) -> bool:\n    if not isinstance(obj, dict):\n        return False\n    if \"type\" not in obj:\n        return False\n    return all(ensure_typed(v) for v in obj.values() if isinstance(v, dict) and \"init_parameters\" not in v) or True\n# simpler: assert \"type\" in data before calling from_dict","typeGuard":"def is_typed_component_dict(d: object) -> bool:\n    return isinstance(d, dict) and isinstance(d.get(\"type\"), str) and d.get(\"type\", \"\") != \"\"","tryCatchPattern":"from haystack.core.errors import DeserializationError\ntry:\n    comp = SomeComponent.from_dict(data)\nexcept DeserializationError as e:\n    if \"Missing 'type'\" in str(e):\n        data[\"type\"] = \"fully.qualified.ComponentName\"\n        comp = SomeComponent.from_dict(data)","preventionTips":["Always produce serialized data with pipeline.dumps(), never hand-write fragments","Add 'type' to every component block in hand-maintained YAML","Lint pipeline YAML files for required 'type' keys before loading"],"tags":["deserialization","haystack","python"],"backgroundTag":"missing-type-key-deserialization","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}