{"record":{"id":"a2291647affb1814","repo":"agentscope-ai/agentscope","slug":"user-message-can-only-contain-text-blocks-or-data","errorCode":null,"errorMessage":"User message can only contain text blocks or data blocks.","messagePattern":"User message can only contain text blocks or data blocks\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/message/_base.py","lineNumber":37,"sourceCode":"    ToolResultBlock,\n    ToolResultState,\n    ContentBlock,\n    ContentBlockTypes,\n)\nfrom ..types import ReplyFinishedReason, ErrorInfo\nfrom .._logging import logger\n\nif TYPE_CHECKING:\n    from ..event import AgentEvent\nelse:\n    AgentEvent = Any\n\n\ndef _assert_user_content_blocks(content: Sequence[ContentBlock]) -> None:\n    \"\"\"Assert that the content blocks in user message are valid.\"\"\"\n    for block in content:\n        if block.type not in [\"text\", \"data\"]:\n            raise ValueError(\n                \"User message can only contain text blocks or data blocks.\",\n            )\n\n\ndef _assert_system_content_blocks(\n    content: Sequence[ContentBlock],\n) -> None:\n    \"\"\"Assert that the content blocks in system message are valid.\"\"\"\n    for block in content:\n        if block.type not in [\"text\"]:\n            raise ValueError(\"System message can only contain text blocks.\")\n\n\ndef _to_blocks(content: str | list) -> list:\n    \"\"\"Convert a plain string to a single-element TextBlock list.\"\"\"\n    if isinstance(content, str):\n        return [TextBlock(text=content)]\n    return content","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/message/_base.py#L19-L55","documentation":"Msg content validation restricts user-role messages to TextBlock and data blocks only; images, audio, video, tool-use blocks, or any other block type in a user message raise this ValueError. This enforces the role/block-type contract used by formatters and models.","triggerScenarios":"Msg(\"user\", role=\"user\", content=[TextBlock(...), ImageBlock(...)]) — any block whose type is not \"text\" or \"data\" inside a user message; also converting third-party message payloads (e.g. multimodal OpenAI content) to Msg without filtering.","commonSituations":"Trying to send an image directly in a user message instead of via the API's expected mechanism (e.g. a dedicated multimodal message type or tool result); assembling messages programmatically without role-specific validation; porting chat histories from other frameworks.","solutions":["Remove non-text/data blocks from user content; move images/media into a tool result or the block type the target model API prescribes for user media","Check the block's .type values before constructing the Msg (see validation code)","Upgrade/check docs: newer agentscope versions may prescribe a specific multimodal user-message pattern"],"exampleFix":"// before\nmsg = Msg(\"user\", content=[TextBlock(type=\"text\", text=\"what is this?\"), ImageBlock(type=\"image\", ...)], role=\"user\")\n\n// after\nmsg = Msg(\"user\", content=[TextBlock(type=\"text\", text=\"what is this?\")], role=\"user\")\n# attach media through the supported channel, e.g. a multimodal/tool-result block per docs","handlingStrategy":"type-guard","validationCode":"allowed = {\"text\", \"data\"}\nassert all(b.type in allowed for b in user_blocks), f\"bad user block: {[b.type for b in user_blocks]}\"","typeGuard":"def is_valid_user_content(blocks) -> bool:\n    return all(b.type in (\"text\", \"data\") for b in blocks)","tryCatchPattern":"try:\n    Msg(\"user\", role=\"user\", content=blocks)\nexcept ValueError as e:\n    if \"text blocks or data blocks\" in str(e):\n        blocks = [b for b in blocks if b.type in (\"text\", \"data\")]","preventionTips":["Build role-specific block factories so user content is validated at creation","Run validate_role_content on assembled histories before sending","Keep media in the message channels the model API actually supports"],"tags":["message","content-validation","user-role"],"backgroundTag":"message-content-validation-failed","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}