langchain-ai/langchain · error · ValueError

Invalid image template: {tmpl}

Error message

Invalid image template: {tmpl}

What it means

In the image-template branch of from_messages/from_template, an image entry whose value is neither str nor dict is rejected with ValueError('Invalid image template'). The branch's type analysis marks this code unreachable (# type: ignore[unreachable]) because the outer isinstance(tmpl, tuple) dispatch should constrain the shape, so hitting it means the dispatch contract was violated (e.g. via unusual subclasses or mutated input).

Source

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

                            template_format=template_format,
                        )
                    elif isinstance(img_template, dict):
                        img_template = dict(img_template)
                        for key in ["url", "path", "detail"]:
                            if key in img_template:
                                input_variables.extend(
                                    get_template_variables(
                                        img_template[key], template_format
                                    )
                                )
                        img_template_obj = ImagePromptTemplate(
                            input_variables=input_variables,
                            template=img_template,
                            template_format=template_format,
                        )
                    else:
                        msg = f"Invalid image template: {tmpl}"  # type: ignore[unreachable]
                        raise ValueError(msg)
                    prompt.append(img_template_obj)
                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)

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Make every image entry either a format string or a dict with keys among 'url', 'path', 'detail'
  2. Validate assembled template lists before passing them to from_messages: assert each payload is str or dict

Example fix

# before
("human", [{"type": "image_url", "image_url": image_bytes}])  # ValueError

# after
("human", [{"type": "image_url", "image_url": {"url": build_url(image_bytes)}}])
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_image_entry(entry) -> bool:
    t = entry.get("image_url") if isinstance(entry, dict) else entry
    return isinstance(t, (str, dict))

Type guard

def is_image_template(t) -> bool:
    return isinstance(t, (str, dict))

Prevention

When it happens

Trigger: Supplying an image message element whose payload is an int, None, bytes, or an object that str/dict checks fail on, typically through dynamically assembled template lists that bypass static typing.

Common situations: Programmatic prompt builders that splice user/config data into message tuples without validating shape; serialization round-trips that turn a dict into something else.

Related errors


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