langchain-ai/langchain · error · ValueError

Invalid template: {template}

Error message

Invalid template: {template}

What it means

The outer guard of BaseChatPromptTemplate.from_template: if the template argument is neither a str nor a Sequence (e.g. an int, a dict at top level, or None), ValueError('Invalid template: {template}') is raised. This is the catch-all after the str branch and the Sequence branch have both failed, and is marked unreachable by type checkers because the annotated type excludes other inputs.

Source

Thrown at libs/core/langchain_core/prompts/chat.py:534

                elif isinstance(tmpl, dict):
                    if template_format == "jinja2":
                        msg = (
                            "jinja2 is unsafe and is not supported for templates "
                            "expressed as dicts. Please use 'f-string' or 'mustache' "
                            "format."
                        )
                        raise ValueError(msg)
                    data_template_obj = DictPromptTemplate(
                        template=cast("dict[str, Any]", tmpl),
                        template_format=template_format,
                    )
                    prompt.append(data_template_obj)
                else:
                    msg = f"Invalid template: {tmpl}"  # type: ignore[unreachable]
                    raise ValueError(msg)
            return cls(prompt=prompt, **kwargs)
        msg = f"Invalid template: {template}"  # type: ignore[unreachable]
        raise ValueError(msg)

    @classmethod
    def from_template_file(
        cls: type[Self],
        template_file: str | Path,
        input_variables: list[str],
        **kwargs: Any,
    ) -> Self:
        """Create a class from a template file.

        Args:
            template_file: path to a template file.
            input_variables: list of input variables.
            **kwargs: Keyword arguments to pass to the constructor.

        Returns:
            A new instance of this class.
        """

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Pass a template string or a list of message templates
  2. If the value arrives from external data, validate isinstance(template, (str, list, tuple)) before calling

Example fix

# before
ChatPromptTemplate.from_template(cfg.get("template"))  # cfg value is None/int

# after
tmpl = cfg.get("template")
if not isinstance(tmpl, (str, list, tuple)):
    msg = f"template must be str or sequence, got {type(tmpl)}"
    raise ValueError(msg)
ChatPromptTemplate.from_template(tmpl)
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_template_arg(t):
    if not isinstance(t, (str, list, tuple)):
        msg = f"template must be str or sequence, got {type(t)}"
        raise ValueError(msg)
    return t

Type guard

def is_template_arg(t) -> bool:
    return isinstance(t, (str, list, tuple))

Prevention

When it happens

Trigger: Calling from_template(template=123), from_template(None), or from_template({'text': ...}) (a top-level dict is not accepted here — dict elements are only valid inside a Sequence).

Common situations: Passing a config-loaded value without checking its type; refactoring code that previously used PromptTemplate.from_template(direct dict); API boundaries where the template comes from user input.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/7807581f35c4b1dc. Report an issue: GitHub.