BerriAI/litellm · error · ValueError

Invalid template message type: {type(template_message)}

Error message

Invalid template message type: {type(template_message)}

What it means

ValueError from Humanloop prompt fetching: the JSON 'template' field must be a dict (single message) or a list (message array); any other JSON type (string, null, number) triggers this. It indicates the Humanloop prompt response schema doesn't match what litellm expects.

Source

Thrown at litellm/integrations/humanloop.py:88

            headers={
                "X-Api-Key": humanloop_api_key,
                "Content-Type": "application/json",
            },
        )

        try:
            response.raise_for_status()
        except httpx.HTTPStatusError as e:
            raise Exception(f"Error getting prompt from Humanloop: {e.response.text}")

        json_response: Final = response.json()
        template_message: Final = json_response["template"]
        if isinstance(template_message, dict):
            template_messages = [template_message]
        elif isinstance(template_message, list):
            template_messages = template_message
        else:
            raise ValueError(f"Invalid template message type: {type(template_message)}")
        template_model: Final = json_response["model"]
        optional_params: Final = {}
        for k, v in json_response.items():
            if k in litellm.OPENAI_CHAT_COMPLETION_PARAMS:
                optional_params[k] = v
        return PromptManagementClient(
            prompt_id=humanloop_prompt_id,
            prompt_template=cast(list[AllMessageValues], template_messages),
            model=template_model,
            optional_params=optional_params,
        )

    def _get_prompt_from_id(self, humanloop_prompt_id: str, humanloop_api_key: str) -> PromptManagementClient:
        prompt = self._get_prompt_from_id_cache(humanloop_prompt_id)
        if prompt is None:
            prompt = self._get_prompt_from_id_api(humanloop_prompt_id, humanloop_api_key)
            self.set_cache(
                key=humanloop_prompt_id,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Open the prompt in Humanloop and confirm it is a chat prompt with a proper message array
  2. Re-fetch the raw API response (curl with X-Api-Key) and inspect the 'template' field's JSON type
  3. Recreate the prompt as a chat-style prompt with at least one message object
  4. Upgrade litellm if a newer release handles the current Humanloop schema
Defensive patterns

Strategy: type-guard

Type guard

def is_valid_template(value) -> bool:
    """Humanloop 'template' must be a message dict or list of message dicts."""
    if isinstance(value, dict):
        return "role" in value or "content" in value
    if isinstance(value, list):
        return all(isinstance(m, dict) for m in value)
    return False

Try / catch

try:
    pmc = get_humanloop_prompt(prompt_id)
except ValueError as e:
    if "Invalid template message type" in str(e):
        raise RuntimeError("Reconfigure the Humanloop prompt as a chat prompt") from e
    raise

Prevention

When it happens

Trigger: A Humanloop prompt of a type whose serialized 'template' is not messages (e.g. a text-completion style prompt or a misconfigured prompt), or 'template' being null in the API response for an empty/invalid prompt. Also possible after Humanloop API schema changes across versions.

Common situations: Using a Humanloop prompt configured as a 'generator' type that returns a string template; deleted/empty prompt returning null; litellm version lagging behind a Humanloop API change; model-type mismatch in the Humanloop project.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/1d2cbee75f025b70. Report an issue: GitHub.