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
- 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.
- Update the component's @component.output_types declaration to reflect the real returned type, and re-run.
- 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
- Keep output_types declarations in sync with actual returned values
- Insert adapter components when connecting differently-typed sockets
- Write a smoke test that runs the full pipeline once with sample data
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
- MarkdownHeaderSplitter only works with text documents but co
- Missing 'type' in component '{name}'
- Successfully imported module '{module}' but couldn't find '{
- Component '{component_type}' (name: '{name}') not imported.
- Couldn't deserialize component '{name}' of class '{component
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/8c9470d11ffd073d.
Report an issue: GitHub.