deepset-ai/haystack · error
Pass either 'responses' or 'response_fn', not both.
Error message
Pass either 'responses' or 'response_fn', not both.
What it means
MockChatGenerator can produce replies either from a canned list (`responses`) or from a callback (`response_fn`), but not both, since the source of replies would be ambiguous. Passing both raises ValueError in __init__.
Source
Thrown at haystack/components/generators/chat/mock.py:128
every call), or a non-empty list of strings and/or `ChatMessage` objects that are returned in order,
cycling back to the start once exhausted. Strings are wrapped into assistant `ChatMessage` objects, and any
`ChatMessage` passed must have the `assistant` role. Mutually exclusive with `response_fn`. If neither is
provided, the component echoes the last message with text content.
:param response_fn: An optional callable that returns the reply as a string or an assistant `ChatMessage`. It
receives the input messages; if it accepts a second positional argument, it also receives the `tools`
passed to `run` (a `ToolsType` or `None`), letting the reply depend on the runtime tool schema. Use this
for input-dependent responses. Mutually exclusive with `responses`. To support serialization, pass a named
function (lambdas and nested functions cannot be serialized).
:param model: The model name reported in the response metadata. Purely cosmetic; no model is loaded.
:param meta: Additional metadata merged into the `meta` of every returned `ChatMessage`. A per-response
`ChatMessage`'s own metadata takes precedence over this value.
:param streaming_callback: An optional callback invoked with `StreamingChunk` objects reconstructed from the
predefined response. It lets the mock exercise streaming code paths without a real model.
:raises ValueError: If both `responses` and `response_fn` are provided, if `responses` is an empty list, or if
a `ChatMessage` response does not have the `assistant` role.
"""
if responses is not None and response_fn is not None:
raise ValueError("Pass either 'responses' or 'response_fn', not both.")
self._responses = self._normalize_responses(responses)
self.response_fn = response_fn
self._response_fn_wants_tools = response_fn is not None and self._response_fn_accepts_tools(response_fn)
self.model = model
self.meta = meta or {}
self.streaming_callback = streaming_callback
self._call_count = 0
self._is_warmed_up = False
@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
View on GitHub (pinned to e318778c9b)
Solutions
- Provide only `responses` for canned replies
- Provide only `response_fn` for dynamic replies; move canned logic into the function if needed
- Check that config/fixture merging doesn't inject a default response_fn
- If you want a canned default with dynamic fallback, wrap both in a single response_fn
Example fix
// before mock = MockChatGenerator(responses=["hi"], response_fn=fn) // after mock = MockChatGenerator(responses=["hi"])
Defensive patterns
Strategy: validation
Validate before calling
assert not (responses is not None and response_fn is not None), "pass either responses or response_fn"
Prevention
- Pick one response strategy per mock; centralize fixture defaults
- When merging configs, let explicit keys override defaults rather than accumulate
- Keep canned replies inside response_fn if dynamic selection is needed
When it happens
Trigger: `MockChatGenerator(responses=[...], response_fn=my_fn)` — providing both arguments in the same call, e.g. when merging defaults and overrides in test setup.
Common situations: Test fixtures that set a global default response_fn and then also pass canned responses; copying an example and adding a second response source; programmatic config merging both keys.
Related errors
- 'responses' must be a string, ChatMessage, or a sequence of
- 'responses' must not be an empty list.
- 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/eafafdcec03117d2.
Report an issue: GitHub.