deepset-ai/haystack · error · DeserializationError

The value of '{key}' is not a dictionary

Error message

The value of '{key}' is not a dictionary

What it means

deserialize_component_inplace found the key but its value is not a dictionary, so it raises DeserializationError. Component serialization data must be a dict containing at least a 'type' field naming the importable class path.

Source

Thrown at haystack/utils/deserialization.py:46

    """
    Deserialize a Component in a dictionary inplace.

    :param data:
        The dictionary with the serialized data.
    :param key:
        The key in the dictionary where the Component is stored. Default is "chat_generator".

    :raises DeserializationError:
        If the key is missing in the serialized data, the value is not a dictionary,
        the type key is missing, the class cannot be imported, or the class lacks a 'from_dict' method.
    """
    if key not in data:
        raise DeserializationError(f"Missing '{key}' in serialization data")

    serialized_component = data[key]

    if not isinstance(serialized_component, dict):
        raise DeserializationError(f"The value of '{key}' is not a dictionary")

    if "type" not in serialized_component:
        raise DeserializationError(f"Missing 'type' in {key} serialization data")

    try:
        component_class = import_class_by_name(serialized_component["type"])
    except ImportError as e:
        raise DeserializationError(f"Class '{serialized_component['type']}' not correctly imported") from e

    data[key] = component_from_dict(cls=component_class, data=serialized_component, name=key)

View on GitHub (pinned to e318778c9b)

Solutions

  1. Ensure the value under the key is a mapping of component-name -> {type, init_parameters}
  2. Fix YAML indentation so components parse as a dict
  3. Regenerate the file with pipeline.dumps()
  4. Validate the input structure before calling from_dict (isinstance(data[key], dict))

Example fix

// before
components:
  - retriever
// after
components:
  retriever:
    type: haystack.components.retrievers.in_memory.InMemoryEmbeddingRetriever
    init_parameters: {}
Defensive patterns

Strategy: validation

Validate before calling

def validate_components(data):
    comps = data.get("components")
    if not isinstance(comps, dict):
        raise ValueError("'components' must be a dict of name -> {type, init_parameters}")
    return comps

Type guard

def are_valid_components(data) -> bool:
    comps = data.get("components") if isinstance(data, dict) else None
    return isinstance(comps, dict) and all(
        isinstance(v, dict) and "type" in v for v in comps.values()
    )

Try / catch

try:
    pipeline = Pipeline.loads(yaml_str)
except DeserializationError as e:
    if "not a dictionary" in str(e):
        logger.error("components section malformed: %s", e)
    raise

Prevention

When it happens

Trigger: Passing data where data[key] is a string, list, or None instead of a dict of component definitions, e.g. components: "foo" or components: [a, b] in the pipeline dict/YAML.

Common situations: YAML where the components value is indented incorrectly and parses as a string or list; loading a hand-edited pipeline; passing the wrong variable to from_dict.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/3f28a2304a620de6. Report an issue: GitHub.