{"record":{"id":"9ecc85a23ae14909","repo":"agentscope-ai/agentscope","slug":"system-message-can-only-contain-text-blocks","errorCode":null,"errorMessage":"System message can only contain text blocks.","messagePattern":"System message can only contain text blocks\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/message/_base.py","lineNumber":48,"sourceCode":"    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\n\n\nclass Usage(BaseModel):\n    \"\"\"The token usage information of a message.\"\"\"\n\n    input_tokens: int\n    \"\"\"The number of input tokens.\"\"\"\n    output_tokens: int\n    \"\"\"The number of output tokens.\"\"\"\n    cache_input_tokens: int = 0\n    \"\"\"The number of input tokens read from the prompt cache.\"\"\"","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/message/_base.py#L30-L66","documentation":"System-role messages are restricted to TextBlock only; any other block type (data, image, tool results) in a system message raises this ValueError during validate_role_content. System prompts are plain text by contract across providers.","triggerScenarios":"Msg(\"system\", role=\"system\", content=[TextBlock(...), DataBlock(...)]) or embedding images/structured data in the system prompt.","commonSituations":"Programmatically building all messages from a uniform block pipeline that injects data blocks into every role; migrating configs where system prompts were templated with structured payloads; concatenating a data block meant for the first user turn.","solutions":["Keep system messages as a single TextBlock (or a plain string)","Move data blocks to the first user message or a tool result","Validate block types per role before constructing Msg objects"],"exampleFix":"// before\nmsg = Msg(\"system\", role=\"system\", content=[\n    TextBlock(type=\"text\", text=\"You are helpful.\"),\n    DataBlock(type=\"data\", data={\"kb\": \"...\"}),\n])\n\n// after\nmsg = Msg(\"system\", role=\"system\", content=\"You are helpful.\")\nfirst_user = Msg(\"user\", role=\"user\", content=[\n    TextBlock(type=\"text\", text=\"Context:\"),\n    DataBlock(type=\"data\", data={\"kb\": \"...\"}),\n])","handlingStrategy":"type-guard","validationCode":"assert all(b.type == \"text\" for b in system_blocks), \"system prompt must be text-only\"","typeGuard":"def is_valid_system_content(blocks) -> bool:\n    return all(b.type == \"text\" for b in blocks)","tryCatchPattern":"try:\n    Msg(\"system\", role=\"system\", content=blocks)\nexcept ValueError as e:\n    if \"only contain text blocks\" in str(e):\n        blocks = [b for b in blocks if b.type == \"text\"]","preventionTips":["Pass system prompts as plain strings","Route structured context/data blocks into user turns or tool results","Validate message histories by role before persisting or replaying them"],"tags":["message","content-validation","system-prompt"],"backgroundTag":"message-content-validation-failed","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}