{"record":{"id":"5b7d600037ccee62","repo":"zylon-ai/private-gpt","slug":"chat-history-does-not-contain-any-user-messages","errorCode":null,"errorMessage":"Chat history does not contain any user messages.","messagePattern":"Chat history does not contain any user messages\\.","errorType":"exception","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"private_gpt/components/chat/processors/chat_history/memory/utils/repairs.py","lineNumber":207,"sourceCode":"            raise ValueError(\n                f\"Chat history contains a tool message: {message.content}. Reason: {reason or 'Unknown'}\"\n            )\n\n\ndef _assert_only_one_user_block(\n    chat_history: list[ChatMessage],\n) -> None:\n    \"\"\"Assert that the chat history contains exactly one user block.\n\n    This is used to ensure that the chat history\n    is clean and contains only one user block.\n    \"\"\"\n    if not chat_history:\n        return\n\n    matrix = get_user_blocks(chat_history)\n    if not matrix:\n        raise ValueError(\"Chat history does not contain any user messages.\")\n    if len(matrix) > 1:\n        raise ValueError(\n            \"Chat history contains multiple user blocks. This is not supported.\"\n        )\n","sourceCodeStart":189,"sourceCodeEnd":212,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/chat/processors/chat_history/memory/utils/repairs.py#L189-L212","documentation":"Raised by _assert_only_one_user_block (used by repair_with_tools) when get_user_blocks returns an empty matrix on a non-empty history: there are messages, but none of them is a user message, so no user block can be formed. repair_with_tools expects exactly one user block, so it aborts.","triggerScenarios":"Calling repair_with_tools() on a conversation containing only assistant/system messages, or where all user messages were filtered/misrouted away upstream.","commonSituations":"System-prompt classification pulling the user message into system_messages; histories loaded with the user turn dropped; test fixtures built without a user message.","solutions":["Ensure the history passed to repair_with_tools contains a user message","Fix upstream splitting so user messages stay in conversation history","Prepend a user message if the pipeline requires one to exist"],"exampleFix":"# before\nrepaired = repair_with_tools(conversation_messages)\n\n# after\nif not any(m.role == \"user\" for m in conversation_messages):\n    conversation_messages = [ChatMessage(role=MessageRole.USER, content=\"(query)\")] + conversation_messages\nrepaired = repair_with_tools(conversation_messages)","handlingStrategy":"validation","validationCode":"if conversation_messages and not any(m.role == \"user\" for m in conversation_messages):\n    raise ValueError(\"cannot repair_with_tools without a user message\")","typeGuard":"def has_user_message(history: list[ChatMessage]) -> bool:\n    return any(m.role == \"user\" for m in history)","tryCatchPattern":"try:\n    repaired = repair_with_tools(conversation_messages)\nexcept ValueError as e:\n    if \"does not contain any user messages\" in str(e):\n        conversation_messages = [ChatMessage(role=MessageRole.USER, content=\"(query)\")] + conversation_messages\n        repaired = repair_with_tools(conversation_messages)\n    else:\n        raise","preventionTips":["Check role presence before choosing the tools repair path","Verify system/conversation splitting didn't swallow the user turn","Write tests with assistant-only histories to catch routing bugs"],"tags":["chat-history","validation","repair","user-message"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}