deepset-ai/haystack · error · PipelineError

Missing sender in connection: {connection}

Error message

Missing sender in connection: {connection}

What it means

While deserializing pipeline connections, each connection entry must name its 'sender'. from_dict validates this before calling connect and raises PipelineError if the key is missing, since a connection without a sender is unresolvable.

Source

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

                        data_str = json.dumps(component_data, default=str, indent=2)
                    except Exception:
                        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:

View on GitHub (pinned to e318778c9b)

Solutions

  1. Add the 'sender' key as "componentName.outputSocket" to the connection entry
  2. Regenerate the connections section with pipe.dumps() from a working pipeline
  3. Validate the sender names against components actually defined in the file

Example fix

// before
connections:
  - receiver: ranker.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 'sender': {c}" for c in data.get("connections", []) if "sender" not in c]

Type guard

def has_sender(conn: dict) -> bool:
    return isinstance(conn, dict) and "sender" in conn

Try / catch

try:
    pipe = Pipeline.from_dict(data)
except PipelineError as e:
    if "Missing sender" 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 without a 'sender' key, e.g. {"receiver": "ranker.documents"}.

Common situations: Hand-writing connections in YAML instead of dumping them; template-generated configs with unfilled sender fields; copy-paste deletions; truncated 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/cc74a8f52902f27f. Report an issue: GitHub.