diff --git a/libs/core/langchain_core/utils/mustache.py b/libs/core/langchain_core/utils/mustache.py index be0739568c2..12cab8da0a3 100644 --- a/libs/core/langchain_core/utils/mustache.py +++ b/libs/core/langchain_core/utils/mustache.py @@ -150,6 +150,11 @@ def parse_tag(template: str, l_del: str, r_del: str) -> tuple[tuple[str, str], s msg = f"unclosed tag at line {_CURRENT_LINE}" raise ChevronError(msg) from e + # Check for empty tags + if not tag.strip(): + msg = f"empty tag at line {_CURRENT_LINE}" + raise ChevronError(msg) + # Find the type meaning of the first character tag_type = tag_types.get(tag[0], "variable") diff --git a/libs/core/tests/unit_tests/prompts/test_structured.py b/libs/core/tests/unit_tests/prompts/test_structured.py index 0b74b37cc6f..fda2d00b367 100644 --- a/libs/core/tests/unit_tests/prompts/test_structured.py +++ b/libs/core/tests/unit_tests/prompts/test_structured.py @@ -2,6 +2,7 @@ from functools import partial from inspect import isclass from typing import Any, Union, cast +import pytest from pydantic import BaseModel from langchain_core.language_models import FakeListChatModel @@ -10,6 +11,7 @@ from langchain_core.load.load import loads from langchain_core.messages import HumanMessage from langchain_core.prompts.structured import StructuredPrompt from langchain_core.runnables.base import Runnable, RunnableLambda +from langchain_core.utils.mustache import ChevronError from langchain_core.utils.pydantic import is_basemodel_subclass @@ -128,3 +130,8 @@ def test_structured_prompt_template_format() -> None: assert prompt.invoke({"person": {"name": "foo"}}).to_messages() == [ HumanMessage("hi foo") ] + + +def test_structured_prompt_template_empty_vars() -> None: + with pytest.raises(ChevronError, match="empty tag"): + StructuredPrompt([("human", "hi {{}}")], schema={}, template_format="mustache")