FoundationAgents/OpenManus · error · ValueError

The last message must be from the user to attach images

Error message

The last message must be from the user to attach images

What it means

Raised by LLM.ask_with_images() when, after formatting, the last message in the list is not role="user". Images are attached by mutating the final user message's content into a multimodal array, so the code requires that anchor point. A trailing assistant or system message makes attachment ambiguous and triggers this guard.

Source

Thrown at app/llm.py:528

            TokenLimitExceeded: If token limits are exceeded
            ValueError: If messages are invalid or response is empty
            OpenAIError: If API call fails after retries
            Exception: For unexpected errors
        """
        try:
            # For ask_with_images, we always set supports_images to True because
            # this method should only be called with models that support images
            if self.model not in MULTIMODAL_MODELS:
                raise ValueError(
                    f"Model {self.model} does not support images. Use a model from {MULTIMODAL_MODELS}"
                )

            # Format messages with image support
            formatted_messages = self.format_messages(messages, supports_images=True)

            # Ensure the last message is from the user to attach images
            if not formatted_messages or formatted_messages[-1]["role"] != "user":
                raise ValueError(
                    "The last message must be from the user to attach images"
                )

            # Process the last user message to include images
            last_message = formatted_messages[-1]

            # Convert content to multimodal format if needed
            content = last_message["content"]
            multimodal_content = (
                [{"type": "text", "text": content}]
                if isinstance(content, str)
                else content
                if isinstance(content, list)
                else []
            )

            # Add images to content
            for image in images:

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Append a user message before calling: messages.append(Message.user_message("Describe this image"))
  2. Strip trailing non-user messages from the history you pass in
  3. Ensure the list is non-empty — check len(messages) > 0 before the call

Example fix

# before
messages = [Message.system_message("you are helpful"), Message.assistant_message("hi")]
await llm.ask_with_images(messages, [img])  # ValueError

# after
messages.append(Message.user_message("describe this image"))
await llm.ask_with_images(messages, [img])
Defensive patterns

Strategy: validation

Validate before calling

def last_message_is_user(messages: list) -> bool:
    return bool(messages) and getattr(messages[-1], "role", None) == "user"

Prevention

When it happens

Trigger: Calling ask_with_images(messages) where messages ends with an assistant message (e.g. pre-populated dialogue), an empty list (formatted_messages is empty), or messages ending with a system message.

Common situations: Reusing a conversation history that ends with the model's last reply; injecting a system-style suffix after the user turn; passing [] accidentally.

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/cc1c60e9ef0f2ae6. Report an issue: GitHub.