deepset-ai/haystack · error
'responses' must not be an empty list.
Error message
'responses' must not be an empty list.
What it means
MockChatGenerator requires at least one canned reply; an empty `responses` list gives the mock nothing to return, so _normalize_responses raises ValueError. Empty strings are allowed, but an empty list is not.
Source
Thrown at haystack/components/generators/chat/mock.py:156
@staticmethod
def _normalize_responses(
responses: str | ChatMessage | Sequence[str | ChatMessage] | None,
) -> list[ChatMessage] | None:
"""Normalize the `responses` argument into a non-empty list of `ChatMessage`, or `None` for echo mode."""
if responses is None:
return None
items: list[str | ChatMessage]
if isinstance(responses, (str, ChatMessage)):
items = [responses]
elif isinstance(responses, Sequence):
items = list(responses)
else:
raise TypeError(f"'responses' must be a string, ChatMessage, or a sequence of them, got {type(responses)}.")
if len(items) == 0:
raise ValueError("'responses' must not be an empty list.")
normalized: list[ChatMessage] = []
for item in items:
if isinstance(item, str):
normalized.append(ChatMessage.from_assistant(item))
elif isinstance(item, ChatMessage):
if item.role != ChatRole.ASSISTANT:
raise ValueError(
f"Each ChatMessage response must have the 'assistant' role, got '{item.role.value}'."
)
normalized.append(item)
else:
raise TypeError(f"Each response must be a string or ChatMessage, got {type(item)}.")
return normalized
def to_dict(self) -> dict[str, Any]:
"""Serialize the component to a dictionary."""
responses = [msg.to_dict() for msg in self._responses] if self._responses is not None else NoneView on GitHub (pinned to e318778c9b)
Solutions
- Provide at least one response, e.g. responses=["ok"]
- Guard construction: fall back to a placeholder response when the list is empty
- If you need a generator that errors or no-ops, use response_fn instead of an empty list
Example fix
// before mock = MockChatGenerator(responses=[]) // after mock = MockChatGenerator(responses=["default reply"])
Defensive patterns
Strategy: validation
Validate before calling
if not responses:
responses = ["placeholder reply"] # or skip creating the mock Type guard
def has_responses(r) -> bool:
if isinstance(r, (str, ChatMessage)):
return True
return isinstance(r, Sequence) and len(r) > 0 Prevention
- Never use [] as a placeholder for fixtures
- Assert non-empty lists in parametrized test setup
- Provide a default canned reply in shared test helpers
When it happens
Trigger: `MockChatGenerator(responses=[])` or passing an empty tuple/sequence, e.g. a list built by filtering that matched nothing, or a default [] in test fixtures.
Common situations: Fixtures with responses=[] as a placeholder never filled; parametrized tests with no cases; YAML/config with an empty array.
Related errors
- Pass either 'responses' or 'response_fn', not both.
- 'responses' must be a string, ChatMessage, or a sequence of
- Each ChatMessage response must have the 'assistant' role, go
- 'dimension' must be a positive integer.
- 'dimension' must be a positive integer.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/534e04decea324ad.
Report an issue: GitHub.