agentscope-ai/agentscope · error · ValueError

The input messages cannot be empty for the `generate_structu

Error message

The input messages cannot be empty for the `generate_structured_output` method.

What it means

generate_structured_output requires a non-empty messages list; calling it with [] raises this ValueError immediately. The messages provide the prompt context the model needs to produce structured output, so an empty list is rejected upfront.

Source

Thrown at src/agentscope/model/_base.py:493

        - ``no_think``: thinking disabled + forced ``tool_choice`` (skipped
          when the provider exposes no thinking toggle)
        - ``none``: current config + no ``tool_choice``

        An explicit ``tool_choice`` in ``kwargs`` bypasses the strategy
        ladder and is forwarded unchanged.

        Args:
            messages (`list[Msg]`):
                The context for LLM to generate the structured output.
            structured_model (`Type[BaseModel] | dict`):
                A Pydantic model or a dict of JSON schemas.

        Returns:
            `StructuredResponse`:
                The structured response generated by the model.
        """
        if len(messages) == 0:
            raise ValueError(
                "The input messages cannot be empty for the "
                "`generate_structured_output` method.",
            )

        user_tool_choice = kwargs.pop("tool_choice", None)
        if user_tool_choice is None:
            forced_tc = ToolChoice(mode="generate_structured_output")
            disable_kwargs = self._get_disable_thinking_kwargs()
            # (name, extra `_call_api` kwargs, tool_choice), best first.
            # The no-think strategy only applies when the provider can
            # toggle it.
            strategies = (
                ("forced", {}, forced_tc),
                ("auto", {}, ToolChoice(mode="auto")),
                *(
                    (("no_think", disable_kwargs, forced_tc),)
                    if disable_kwargs
                    else ()

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Pass at least one message, typically the instruction prompt: generate_structured_output([Msg('user', 'extract fields: ...')], Schema)
  2. Guard the call site: if not messages: skip or supply a default prompt
  3. Log the message list length before calling to find where it becomes empty

Example fix

# before
res = await model.generate_structured_output([], Schema)

# after
res = await model.generate_structured_output(
    [Msg('user', 'Extract the fields from the given text.')], Schema)
Defensive patterns

Strategy: validation

Validate before calling

if not messages:
    raise ValueError('nothing to structure')  # or supply a default prompt
res = await model.generate_structured_output(messages, Schema)

Type guard

def has_messages(msgs: list) -> bool:
    return isinstance(msgs, list) and len(msgs) > 0

Prevention

When it happens

Trigger: Calling model.generate_structured_output([], MySchema) or passing a messages list that was built from an empty conversation / filtered to nothing.

Common situations: Programmatically building a message list from user input that turns out empty; slicing history incorrectly (e.g. messages[10:]) so the list is empty; refactoring a call path that previously checked length.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/115d7eb7c289132f. Report an issue: GitHub.