{"record":{"id":"701e2915258f91d9","repo":"BerriAI/litellm","slug":"unsupported-content-type-type-content-block","errorCode":null,"errorMessage":"Unsupported content type: {type(content_block)}","messagePattern":"Unsupported content type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/prompt_templates/factory.py","lineNumber":4130,"sourceCode":"        modified_content_block: Final = content_block.copy()\n\n        for item in modified_content_block:\n            # Check if the list is empty\n            if item[\"type\"] == \"text\":\n                if not item[\"text\"].strip():\n                    # Replace empty text with continue message\n                    _user_continue_message = ChatCompletionUserMessage(\n                        **(user_continue_message or DEFAULT_USER_CONTINUE_MESSAGE)\n                    )\n                    text = convert_content_list_to_str(_user_continue_message)\n                    item[\"text\"] = text\n                    break\n        modified_message: Final = message.copy()\n        modified_message[\"content\"] = modified_content_block\n        return modified_message\n\n    # Handle unsupported type\n    raise ValueError(f\"Unsupported content type: {type(content_block)}\")\n\n\ndef return_assistant_continue_message(\n    assistant_continue_message: str | ChatCompletionAssistantMessage | None = None,\n) -> ChatCompletionAssistantMessage:\n    if assistant_continue_message and isinstance(assistant_continue_message, str):\n        return ChatCompletionAssistantMessage(\n            role=\"assistant\",\n            content=assistant_continue_message,\n        )\n    elif assistant_continue_message and isinstance(assistant_continue_message, dict):\n        return ChatCompletionAssistantMessage(**assistant_continue_message)\n    else:\n        return DEFAULT_ASSISTANT_CONTINUE_MESSAGE\n\n\ndef _skip_empty_dict_blocks(blocks: list[dict]) -> list[dict]:\n    \"\"\"","sourceCodeStart":4112,"sourceCodeEnd":4148,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/prompt_templates/factory.py#L4112-L4148","documentation":"Raised while normalizing a user message's content for empty-text replacement (the function that swaps empty text blocks for a 'continue' message). It explicitly handles content being a str or a list of blocks; any other Python type — None, dict, int — hits the final ValueError.","triggerScenarios":"A message whose 'content' key is None (common when a user message has tool results but content omitted), a single content-block dict instead of a list, or any non-str/non-list value, sent to a Bedrock Converse model.","commonSituations":"Messages built for OpenAI tool flows where content is optional; agent frameworks that emit content=None for tool-result turns; passing one content block as a bare dict {\"type\":\"text\",...} instead of wrapping it in a list.","solutions":["Set user message content to a non-empty string, or to a list of typed blocks.","If content is None because of tool results, supply content: \"\" is not enough — use an explicit text block or omit the user message and use the tool role expected by the handler.","Wrap single blocks in a list: content=[{\"type\":\"text\",\"text\":\"...\"}]."],"exampleFix":"# before\n{\"role\": \"user\", \"content\": None}\n# after\n{\"role\": \"user\", \"content\": [{\"type\": \"text\", \"text\": \" \"}]}","handlingStrategy":"type-guard","validationCode":"def sanitize_content(msg: dict) -> dict:\n    c = msg.get(\"content\")\n    if c is None:\n        msg = {**msg, \"content\": [{\"type\": \"text\", \"text\": \" \"}]}\n    elif isinstance(c, dict):\n        msg = {**msg, \"content\": [c]}\n    return msg","typeGuard":"def content_is_supported(c) -> bool:\n    return isinstance(c, (str, list))","tryCatchPattern":"try:\n    resp = litellm.completion(model=\"bedrock/...\", messages=msgs)\nexcept ValueError as e:\n    if \"Unsupported content type\" in str(e):\n        msgs = [sanitize_content(m) for m in msgs]\n        resp = litellm.completion(model=\"bedrock/...\", messages=msgs)","preventionTips":["Never leave user-message content as None; always set a string or block list.","Run a message-schema validator over outgoing payloads in CI."],"tags":["bedrock","message-format","content-blocks","input-validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}