{"record":{"id":"f665caea0d6deafd","repo":"zylon-ai/private-gpt","slug":"the-last-user-message-exceeds-the-maximum-length-a","errorCode":null,"errorMessage":"The last user message exceeds the maximum length allowed.","messagePattern":"The last user message exceeds the maximum length allowed\\.","errorType":"exception","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"private_gpt/components/chat/processors/chat_history/memory/strategies/condenser.py","lineNumber":777,"sourceCode":"        (\n            left_messages,\n            last_user_message,\n            right_messages,\n        ) = await asyncio.to_thread(self._split_conversation, chat_history.copy())\n\n        # Select LLM and tokenizer\n        model_id: str | None = kwargs.get(\"model_id\")\n        llm = self.llm_component.get_llm(model_id)\n        tokenizer = self.llm_component.get_tokenizer(model_id)\n\n        left_tokens, last_user_message_tokens, right_tokens = await asyncio.gather(\n            self._get_messages_tokens(left_messages, tokenizer_fn=tokenizer),\n            self._get_messages_tokens(last_user_message, tokenizer_fn=tokenizer),\n            self._get_messages_tokens(right_messages, tokenizer_fn=tokenizer),\n        )\n\n        if last_user_message_tokens > max_length:\n            raise ValueError(\n                \"The last user message exceeds the maximum length allowed.\"\n            )\n        if left_tokens + last_user_message_tokens + right_tokens <= max_length:\n            return chat_history\n\n        # Decide in which direction we will go\n        left_token_percentage = left_tokens / (\n            left_tokens + right_tokens + last_user_message_tokens\n        )\n        right_token_percentage = right_tokens / (\n            left_tokens + right_tokens + last_user_message_tokens\n        )\n        diff_tokens = right_token_percentage - left_token_percentage\n\n        # If there exists a significant difference in left token distribution,\n        # we will perform condensation from the left side\n        if diff_tokens <= 0.1:\n            chat_history = await self._condense_from_left(","sourceCodeStart":759,"sourceCodeEnd":795,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/chat/processors/chat_history/memory/strategies/condenser.py#L759-L795","documentation":"ValueError from the condenser's main condense path. It tokenizes left messages, the last user message, and right messages; if the last user message alone exceeds max_length, no amount of condensing can help (the last user message is always preserved by design), so it fails fast rather than looping.","triggerScenarios":"A single huge user prompt (e.g. pasted document or long code) whose token count > condense max_length; max_length misconfigured to a value smaller than a typical user turn; tokenizer change inflating counts.","commonSituations":"Users pasting entire files into chat; context budget set near the model's output token limit rather than input limit; RAG flows injecting retrieved chunks into the user message.","solutions":["Increase max_length so it accommodates the largest legitimate user message.","Pre-process oversized user messages: summarize, chunk, or move document content into retrieval instead of the prompt.","Validate incoming message size at the API boundary and reject with a clear 413-style error before condensing.","Catch the ValueError and respond to the client asking to shorten the prompt."],"exampleFix":"// before\nuser_msg = open('huge_file.txt').read()   # 50k tokens\nawait condenser.condense(history)          # ValueError\n\n// after\nuser_msg = summarize_or_chunk(open('huge_file.txt').read())\nawait condenser.condense(history)","handlingStrategy":"validation","validationCode":"last_user_tokens = await estimate_token_count(last_user_message, tokenizer_fn=tokenizer)\nif last_user_tokens > max_length:\n    raise HTTPException(413, f\"Prompt too large: {last_user_tokens} tokens > budget {max_length}\")","typeGuard":"def user_message_fits(msg: ChatMessage, max_length: int, tokenizer) -> bool:\n    import asyncio\n    return asyncio.get_event_loop().run_until_complete(estimate_token_count(msg, tokenizer_fn=tokenizer)) <= max_length","tryCatchPattern":"try:\n    condensed = await condenser.condense(history)\nexcept ValueError as e:\n    if \"last user message exceeds\" in str(e):\n        raise HTTPException(413, \"Please shorten your message\") from e\n    raise","preventionTips":["Check incoming user prompt size at the API boundary.","Move large documents to RAG/retrieval instead of inline prompts.","Set max_length above the largest legitimate user turn.","Return actionable 413 responses instead of 500s."],"tags":["condensation","context-window","prompt-size","chat-history"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}