BerriAI/litellm · error · ValueError
`prompt` must be a non-empty string or a non-empty list of…
Error message
`prompt` must be a non-empty string or a non-empty list of strings. Got: {prompt_type_name}. What it means
When routing a completion-style prompt to a chat-shaped provider, litellm converts it into user messages. It accepts only a non-empty string or a list of non-empty strings; pre-tokenized prompts (list[int] / list[list[int]]) are rejected because they only make sense for OpenAI-family text endpoints, as are empty values which every chat provider rejects downstream.
Solutions
- Pass a non-empty string, or a list where every element is a non-empty string
- For token-id prompts, use the OpenAI-family text completion endpoints instead of chat
- Guard upstream: replace empty prompts with a placeholder like '.' or reject them in your handler
Example fix
# before litellm.completion(model="gpt-4o-mini", prompt=[]) litellm.completion(model="gpt-4o-mini", prompt=[101, 102]) # after litellm.completion(model="gpt-4o-mini", prompt="Hello") litellm.completion(model="gpt-4o-mini", prompt=["Hello", "world"])
Defensive patterns
Strategy: type-guard
Validate before calling
from typing import Sequence
def normalize_prompt(prompt):
"""Return a chat-safe prompt or None if unusable."""
if isinstance(prompt, str) and prompt.strip():
return prompt
if isinstance(prompt, Sequence) and not isinstance(prompt, (str, bytes)):
if all(isinstance(x, str) and x.strip() for x in prompt) and len(prompt) > 0:
return list(prompt)
return None
# safe_prompt = normalize_prompt(prompt)
# if safe_prompt is None: reject/handle before calling litellm Type guard
from collections.abc import Sequence
from typing import TypeGuard
def is_valid_chat_prompt(prompt: object) -> TypeGuard[str | list[str]]:
if isinstance(prompt, str):
return bool(prompt)
if isinstance(prompt, Sequence) and not isinstance(prompt, (str, bytes)):
return bool(prompt) and all(isinstance(p, str) and p for p in prompt)
return False Try / catch
try:
litellm.completion(model=model, prompt=prompt)
except ValueError as e:
if "must be a non-empty string" in str(e):
prompt = "." # or reject the request upstream
else:
raise Prevention
- Never forward token-id arrays to chat-shaped models; route them to text completion endpoints
- Default empty user input to a placeholder or reject it at the API boundary
- Unit-test prompt normalization for '', [], [1, 2], ['a', None] inputs
When it happens
Trigger: Calling with prompt='' or prompt=[], prompt=[1, 2, 3] (token ids), or a list that mixes strings with non-string entries such that string_entries != entries.
Common situations: Porting completion code that used token arrays to a chat model; passing None or '' when user input is empty; dynamically built prompts that end up blank.
Related errors
- Amazon Nova Canvas requires a text prompt. Pass a non-empty…
- file_id and file_data are both None
- audience must be provided unless…
- BFL error
- Both 'sentinel_nodes' and 'service_name' are required for…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/cc2d0c23ed3491d1.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/litellm_core_utils/prompt_templates/common_utils.py:1878
def text_completion_prompt_to_messages(prompt: object) -> tuple[AllMessageValues, ...]:
"""
Wrap an OpenAI ``/v1/completions`` ``prompt`` into Chat Completion messages.
Mirrors what ``litellm.text_completion`` does on the real-time path: a
string becomes a single user message, and a list of strings becomes one
user message per element. Pre-tokenized prompts (``list[int]`` /
``list[list[int]]``) are only meaningful for the OpenAI-family text
endpoints, so they are rejected here rather than silently forwarded, as is
an empty prompt, which every chat-shaped provider rejects downstream.
"""
prompt_type_name: Final = type(prompt).__name__
if isinstance(prompt, str) and prompt:
return (ChatCompletionUserMessage(role="user", content=prompt),)
entries: Final = cast("Sequence[object]", prompt) if isinstance(prompt, Sequence) else ()
string_entries: Final = tuple(entry for entry in entries if isinstance(entry, str) and entry)
if string_entries and len(string_entries) == len(entries):
return tuple(ChatCompletionUserMessage(role="user", content=entry) for entry in string_entries)
raise ValueError(f"`prompt` must be a non-empty string or a non-empty list of strings. Got: {prompt_type_name}.")
View on GitHub (pinned to 77b7c6c40c)