deepset-ai/haystack · error · PipelineRuntimeError

Failed to perform conversion between components:\nSender com

Error message

Failed to perform conversion between components:\nSender component: '${component_name}' (type: '${sender_type_name}')\nSender socket: '${sender_socket.name}'\nReceiver component: '${receiver_name}' (type: '${receiver_type_name}')\nReceiver socket: '${receiver_socket.name}'\nError: {e}

What it means

PipelineBase._write_component_outputs wraps any exception raised while converting a sender component's output to the receiver socket's expected type into a PipelineRuntimeError with a detailed sender/receiver diagnostic. The underlying cause (the chained exception) is usually a type-conversion failure between mismatched connected sockets.

Source

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

                    value = _convert_value(value=value, conversion_strategy=conversion_strategy)
                except Exception as e:
                    sender_node = self.graph.nodes.get(component_name)
                    sender_instance = sender_node.get("instance") if sender_node else None
                    sender_type_name = type(sender_instance).__name__ if sender_instance else "unknown"

                    receiver_node = self.graph.nodes.get(receiver_name)
                    receiver_instance = receiver_node.get("instance") if receiver_node else None
                    receiver_type_name = type(receiver_instance).__name__ if receiver_instance else "unknown"

                    msg = (
                        f"Failed to perform conversion between components:\n"
                        f"Sender component: '{component_name}' (type: '{sender_type_name}')\n"
                        f"Sender socket: '{sender_socket.name}'\n"
                        f"Receiver component: '{receiver_name}' (type: '{receiver_type_name}')\n"
                        f"Receiver socket: '{receiver_socket.name}'\n"
                        f"Error: {e}"
                    )
                    raise PipelineRuntimeError(component_name=None, component_type=None, message=msg) from e

            if receiver_name not in inputs:
                inputs[receiver_name] = {}

            if receiver_socket.is_lazy_variadic:
                # If the receiver socket is lazy variadic, we append the new input.
                # Lazy variadic sockets can collect multiple inputs.
                _write_to_lazy_variadic_socket(
                    inputs=inputs,
                    receiver_name=receiver_name,
                    receiver_socket_name=receiver_socket.name,
                    component_name=component_name,
                    value=value,
                )
            else:
                # If the receiver socket is not lazy variadic, it is greedy variadic or non-variadic.
                # We overwrite with the new input if it's not a _NoOutputProduced marker, or if the current value
                # is None.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Read the chained 'Error: ...' cause to identify the actual conversion failure, then fix the producing component's output to match the declared receiver input type.
  2. Update the component's @component.output_types declaration to reflect the real returned type, and re-run.
  3. Reconnect with a compatible socket or insert an adapter component that converts between the two types.

Example fix

// before
@component
class MyComp:
    @component.output_types
    def run(self) -> dict[str, str]: ...  # returns list[str]
// after
@component
class MyComp:
    @component.output_types
    def run(self) -> list[str]: ...
Defensive patterns

Strategy: try-catch

Validate before calling

from haystack.core.type_utils import _type_name
sender_out = pipeline.graph.edges["a", "b"]["conn_type"]
# check declared types align before running
assert sender_out is not None, "connected sockets have incompatible types"

Type guard

def types_compatible(sender_type, receiver_type) -> bool:
    try:
        return receiver_type in {sender_type} or issubclass(sender_type, receiver_type)
    except TypeError:
        return sender_type == receiver_type

Try / catch

try:
    result = pipeline.run(data)
except PipelineRuntimeError as e:
    logger.error("Conversion failed between components: %s", e)

Prevention

When it happens

Trigger: pipeline.connect() between sockets of incompatible types where output type adaptation fails at runtime; a component's run() returns a value whose type does not match the declared output socket type of the connected receiver input.

Common situations: Connecting a custom component whose declared output type drifted from the receiver's declared input type after refactoring; returning a List[str] where the receiver expects a Document list; third-party components updated to new types without updating connections.

Related errors


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