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
- Open the prompt in Humanloop and confirm it is a chat prompt with a proper message array
- Re-fetch the raw API response (curl with X-Api-Key) and inspect the 'template' field's JSON type
- Recreate the prompt as a chat-style prompt with at least one message object
- 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
- Create Humanloop prompts as chat-type with message arrays
- Inspect raw API responses when integrating new prompt types
- Keep litellm updated for Humanloop schema changes
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
- prompt_id is required for Humanloop integration
- prompt_id is required for GitLab prompt manager
- Error getting prompt from Humanloop: {e.response.text}
- soft_budget cannot be negative. Received: {data.soft_budget}
- soft_budget ({data.soft_budget}) must be strictly lower than
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/1d2cbee75f025b70.
Report an issue: GitHub.