deepset-ai/haystack · error · PipelineError

Missing receiver in connection: {connection}

Error message

Missing receiver in connection: {connection}

What it means

The mirror of the sender check: each serialized connection must specify a 'receiver'. from_dict raises PipelineError when the 'receiver' key is absent, because connect() requires both endpoints to wire the pipeline.

Source

Thrown at haystack/core/pipeline/base.py:289

                        data_str = str(component_data)

                    max_len = 1000
                    if len(data_str) > max_len:
                        data_str = data_str[:max_len] + "\n... (truncated)"

                    msg = (
                        f"Couldn't deserialize component '{name}' of class '{component_class.__name__}' "
                        f"with the following data:\n{data_str}\n\n"
                        f"Original error: {e}"
                    )
                    raise DeserializationError(msg) from e
            pipe.add_component(name=name, instance=instance)

        for connection in data.get("connections", []):
            if "sender" not in connection:
                raise PipelineError(f"Missing sender in connection: {connection}")
            if "receiver" not in connection:
                raise PipelineError(f"Missing receiver in connection: {connection}")
            pipe.connect(sender=connection["sender"], receiver=connection["receiver"])

        return pipe

    def dumps(self, marshaller: Marshaller = DEFAULT_MARSHALLER) -> str:
        """
        Returns the string representation of this pipeline according to the format dictated by the `Marshaller` in use.

        :param marshaller:
            The Marshaller used to create the string representation. Defaults to `YamlMarshaller`.
        :returns:
            A string representing the pipeline.
        """
        return marshaller.marshal(self.to_dict())

    def dump(self, fp: TextIO, marshaller: Marshaller = DEFAULT_MARSHALLER) -> None:
        """
        Writes the string representation of this pipeline to the file-like object passed in the `fp` argument.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Add the 'receiver' key as "componentName.inputSocket" to the connection entry
  2. Re-dump the pipeline with pipe.dumps() to get a canonical connections list
  3. Cross-check both sender and receiver exist in the 'components' section

Example fix

// before
connections:
  - sender: retriever.documents

// after
connections:
  - sender: retriever.documents
    receiver: ranker.documents
Defensive patterns

Strategy: validation

Validate before calling

def validate_connections(data: dict) -> list[str]:
    return [f"connection missing 'receiver': {c}" for c in data.get("connections", []) if "receiver" not in c]

Type guard

def has_receiver(conn: dict) -> bool:
    return isinstance(conn, dict) and "receiver" in conn

Try / catch

try:
    pipe = Pipeline.from_dict(data)
except PipelineError as e:
    if "Missing receiver" in str(e):
        logging.error("Fix the connections list: %s", e)

Prevention

When it happens

Trigger: from_dict on pipeline data whose 'connections' list contains an entry like {"sender": "retriever.documents"} with no 'receiver' key.

Common situations: Hand-edited YAML dropping the receiver line; generators emitting partial connections; merge conflicts resolved incorrectly in pipeline config files.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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