BerriAI/litellm · error · Exception
Prop `type` is not a string
Error message
Prop `type` is not a string
What it means
Before sending messages to Bytez, LiteLLM normalizes each content part; this guard fires when a content-part dict has no 'type' key or a falsy 'type' (empty string/None). Every part must carry a non-empty type string so it can be looked up in open_ai_to_bytez_content_item_map.
Solutions
- Give every content part a valid 'type' ("text", "image_url", "input_audio", "video_url").
- Validate parts with a small helper before calling bytez models.
- When wrapping plain strings, let litellm normalize by using a plain string content or {"type":"text","text":...}.
Example fix
# before
messages = [{"role": "user", "content": [{"text": "hi"}]}]
# after
messages = [{"role": "user", "content": [{"type": "text", "text": "hi"}]}] Defensive patterns
Strategy: validation
Validate before calling
def content_parts_valid(content: list) -> bool:
return all(
isinstance(p, dict) and isinstance(p.get("type"), str) and p["type"]
for p in content
) Type guard
def is_typed_content_part(part: object) -> bool:
return isinstance(part, dict) and isinstance(part.get("type"), str) and len(part["type"]) > 0 Try / catch
try:
litellm.completion(model="bytez/org/model", messages=messages)
except Exception as e:
if "`type` is not a string" in str(e):
messages = normalize_parts(messages) # ensure every part has a type
litellm.completion(model="bytez/org/model", messages=messages)
else:
raise Prevention
- Always emit parts through a builder that sets 'type' explicitly.
- Never splice optional dicts into content without checking for the 'type' key.
When it happens
Trigger: A message like {"role": "user", "content": [{"text": "hi"}]} (missing type), or {"type": "", "text": "hi"}; programmatically built parts where the type field was dropped; mixing raw strings inside a dict part by mistake.
Common situations: Hand-rolled prompt assemblers; parts produced by another SDK with different casing (e.g. 'kind' instead of 'type'); data corruption or empty dicts slipping into content lists.
Related errors
- Prop ` ` is not a string
- `content` can only contain strings or openai content dicts
- kwarg `messages` must be an array of messages that follow…
- Prop ` ` is not supported
- Each content item must be a dictionary
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/8cecb80d89894194.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/llms/bytez/chat/transformation.py:393
}
def adapt_messages_to_bytez_standard(messages: list[dict]):
messages = _adapt_string_only_content_to_lists(messages)
new_messages: Final = []
for message in messages:
role = message["role"]
content: list = message["content"]
new_content = []
for content_item in content:
type: str | None = content_item.get("type")
if not type:
raise Exception("Prop `type` is not a string")
content_item_map = open_ai_to_bytez_content_item_map[type]
if not content_item_map:
raise Exception(f"Prop `{type}` is not supported")
new_type = content_item_map["type"]
value_name = content_item_map["value_name"]
value: str | None = content_item.get(value_name)
if not value:
raise Exception(f"Prop `{value_name}` is not a string")
new_content.append({"type": new_type, value_name: value})
new_messages.append({"role": role, "content": new_content})View on GitHub (pinned to 77b7c6c40c)