{"record":{"id":"534e04decea324ad","repo":"deepset-ai/haystack","slug":"responses-must-not-be-an-empty-list","errorCode":null,"errorMessage":"'responses' must not be an empty list.","messagePattern":"'responses' must not be an empty list\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"haystack/components/generators/chat/mock.py","lineNumber":156,"sourceCode":"\n    @staticmethod\n    def _normalize_responses(\n        responses: str | ChatMessage | Sequence[str | ChatMessage] | None,\n    ) -> list[ChatMessage] | None:\n        \"\"\"Normalize the `responses` argument into a non-empty list of `ChatMessage`, or `None` for echo mode.\"\"\"\n        if responses is None:\n            return None\n\n        items: list[str | ChatMessage]\n        if isinstance(responses, (str, ChatMessage)):\n            items = [responses]\n        elif isinstance(responses, Sequence):\n            items = list(responses)\n        else:\n            raise TypeError(f\"'responses' must be a string, ChatMessage, or a sequence of them, got {type(responses)}.\")\n\n        if len(items) == 0:\n            raise ValueError(\"'responses' must not be an empty list.\")\n\n        normalized: list[ChatMessage] = []\n        for item in items:\n            if isinstance(item, str):\n                normalized.append(ChatMessage.from_assistant(item))\n            elif isinstance(item, ChatMessage):\n                if item.role != ChatRole.ASSISTANT:\n                    raise ValueError(\n                        f\"Each ChatMessage response must have the 'assistant' role, got '{item.role.value}'.\"\n                    )\n                normalized.append(item)\n            else:\n                raise TypeError(f\"Each response must be a string or ChatMessage, got {type(item)}.\")\n        return normalized\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"Serialize the component to a dictionary.\"\"\"\n        responses = [msg.to_dict() for msg in self._responses] if self._responses is not None else None","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/generators/chat/mock.py#L138-L174","documentation":"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.","triggerScenarios":"`MockChatGenerator(responses=[])` or passing an empty tuple/sequence, e.g. a list built by filtering that matched nothing, or a default [] in test fixtures.","commonSituations":"Fixtures with responses=[] as a placeholder never filled; parametrized tests with no cases; YAML/config with an empty array.","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"],"exampleFix":"// before\nmock = MockChatGenerator(responses=[])\n// after\nmock = MockChatGenerator(responses=[\"default reply\"])","handlingStrategy":"validation","validationCode":"if not responses:\n    responses = [\"placeholder reply\"]  # or skip creating the mock","typeGuard":"def has_responses(r) -> bool:\n    if isinstance(r, (str, ChatMessage)):\n        return True\n    return isinstance(r, Sequence) and len(r) > 0","tryCatchPattern":null,"preventionTips":["Never use [] as a placeholder for fixtures","Assert non-empty lists in parametrized test setup","Provide a default canned reply in shared test helpers"],"tags":["mock","validation","empty-list","testing"],"backgroundTag":"empty-collection-argument","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}