langchain-ai/langchain · error · ValueError

Invalid input type {type(model_input)}. Must be a PromptValu

Error message

Invalid input type {type(model_input)}. Must be a PromptValue, str, or list of BaseMessages.

What it means

`ValueError` from `BaseLLM._convert_input`: completion-style LLMs accept a `str` prompt, a `PromptValue`, or a `Sequence` of messages (converted via `convert_to_messages`). Any other type — dict, single `BaseMessage`, generator, `None`, int — is rejected before the request is built.

Source

Thrown at libs/core/langchain_core/language_models/llms.py:332

    @property
    @override
    def OutputType(self) -> type[str]:
        """Get the output type for this `Runnable`."""
        return str

    def _convert_input(self, model_input: LanguageModelInput) -> PromptValue:
        if isinstance(model_input, PromptValue):
            return model_input
        if isinstance(model_input, str):
            return StringPromptValue(text=model_input)
        if isinstance(model_input, Sequence):
            return ChatPromptValue(messages=convert_to_messages(model_input))
        msg = (  # type: ignore[unreachable]
            f"Invalid input type {type(model_input)}. "
            "Must be a PromptValue, str, or list of BaseMessages."
        )
        raise ValueError(msg)

    def _get_ls_params(
        self,
        stop: list[str] | None = None,
        **kwargs: Any,
    ) -> LangSmithParams:
        """Get standard params for tracing."""
        # get default provider from class name
        default_provider = self.__class__.__name__
        default_provider = default_provider.removesuffix("LLM")
        default_provider = default_provider.lower()

        ls_params = LangSmithParams(ls_provider=default_provider, ls_model_type="llm")
        if stop:
            ls_params["ls_stop"] = stop

        # model
        if "model" in kwargs and isinstance(kwargs["model"], str):

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Pass a plain string for completion LLMs: `llm.invoke("hello")`.
  2. Wrap single messages in a list, or use a `ChatModel` for message-based flows.
  3. Add explicit `None` checks upstream for optional prompt variables.
  4. Type call sites as `LanguageModelInput` for static verification.

Example fix

# before
resp = llm.invoke(HumanMessage(content="hi"))  # ValueError

# after
resp = llm.invoke("hi")
# or
resp = llm.invoke([HumanMessage(content="hi")])
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Sequence
from langchain_core.prompt_values import PromptValue
if not isinstance(prompt, (str, PromptValue, Sequence)):
    prompt = [prompt]  # or raise with a clear message

Type guard

def is_valid_llm_input(value: object) -> bool:
    return isinstance(value, (str, PromptValue)) or isinstance(value, Sequence)

Try / catch

try:
    out = llm.invoke(prompt)
except ValueError as e:
    if "Invalid input type" in str(e):
        out = llm.invoke(str(prompt))
    else:
        raise

Prevention

When it happens

Trigger: Calling `llm.invoke(msg)` with a bare message instead of `[msg]`; passing `None`; passing a dict prompt; passing a generator of prompts; passing an int/float from a data bug.

Common situations: Reusing chat-model call patterns on `LLM` objects; dynamic pipelines where a variable can be `None`; refactors that changed the input type without updating call sites.

Related errors


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