{"record":{"id":"5e333e2904c2736d","repo":"deepset-ai/haystack","slug":"message-content-in-template-is-empty-or-contains-o","errorCode":null,"errorMessage":"Message content in template is empty or contains only whitespace characters. Content: {content!r}","messagePattern":"Message content in template is empty or contains only whitespace characters\\. Content: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/utils/jinja2_chat_extension.py","lineNumber":301,"sourceCode":"\n    @staticmethod\n    def _parse_content_parts(content: str, start_tag: str, end_tag: str) -> list[ChatMessageContentT]:\n        \"\"\"\n        Parse a string into a sequence of ChatMessageContentT objects.\n\n        This method handles:\n        - Plain text content, converted to TextContent objects\n        - Structured content parts wrapped in sentinel tags, converted to ChatMessageContentT objects\n\n        :param content: Input string containing mixed text and content parts\n        :param start_tag: The opening sentinel tag (including the nonce)\n        :param end_tag: The closing sentinel tag (including the nonce)\n        :return: A list of ChatMessageContentT objects\n        :raises ValueError: If the content is empty or contains only whitespace characters or if a\n                            `<haystack_content_part>` tag is found without a matching closing tag.\n        \"\"\"\n        if not content.strip():\n            raise ValueError(\n                f\"Message content in template is empty or contains only whitespace characters. \"\n                f\"Content: {_redact_nonce(content, start_tag, end_tag)!r}\"\n            )\n\n        parts: list[ChatMessageContentT] = []\n        cursor = 0\n        total_length = len(content)\n\n        while cursor < total_length:\n            tag_start = content.find(start_tag, cursor)\n\n            if tag_start == -1:\n                # No more tags, add remaining text if any\n                remaining_text = content[cursor:].strip()\n                if remaining_text:\n                    parts.append(TextContent(text=remaining_text))\n                break\n","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/utils/jinja2_chat_extension.py#L283-L319","documentation":"During template rendering, a message block produced content that is empty or whitespace-only after parsing the sentinel-tagged content parts. Haystack rejects this because a ChatMessage cannot be built from empty content.","triggerScenarios":"A Jinja2 expression inside a message block evaluates to an empty string, None, or only whitespace (e.g. {{ optional_var }} where the variable is empty), and the message carries no content parts.","commonSituations":"Optional context variables that end up empty; a filter that strips content (e.g. truncate to 0); loops that produce nothing; templates where a variable name is misspelled and renders as empty.","solutions":["Ensure the expression inside the message block always yields non-empty text, e.g. {{ var or \"default\" }}.","Guard with Jinja2 conditionals: {% if var %}...{% endif %} around the message content.","Check the pipeline variables passed to the template renderer for empty/None values.","Verify the variable names in the template match the provided variables dict exactly."],"exampleFix":"// before\n\"\"\"User message: {{ query }}\"\"\"  # query is empty\n// after\n\"\"\"User message: {{ query or \"(no query provided)\" }}\"\"\"","handlingStrategy":"validation","validationCode":"def validate_template_vars(vars: dict):\n    for k, v in vars.items():\n        if v is None or (isinstance(v, str) and not v.strip()):\n            raise ValueError(f\"Template variable '{k}' is empty or whitespace-only\")","typeGuard":"def has_content(v) -> bool:\n    return v is not None and (not isinstance(v, str) or bool(v.strip()))","tryCatchPattern":"try:\n    messages = renderer.run(template=tpl, variables=vars)[\"messages\"]\nexcept ValueError as e:\n    if \"empty or contains only whitespace\" in str(e):\n        raise ValueError(f\"Template produced empty message; check variables: {list(vars)}\") from e\n    raise","preventionTips":["Use Jinja2 defaults: {{ var or \"fallback\" }} or {% if var %} guards.","Validate all template variables for emptiness before rendering.","Avoid filters that can produce empty strings (e.g. truncate(0)).","Double-check variable name spelling against the variables dict."],"tags":["jinja2","chat-template","empty-content"],"backgroundTag":"empty-template-content","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}