agentscope-ai/agentscope · error · ValueError

Exactly one of `data` or `url` must be provided.

Error message

Exactly one of `data` or `url` must be provided.

What it means

A pydantic model_validator on the event model enforces that binary content carries exactly one of `data` (inline bytes) or `url` (remote reference). Both set, or both None, makes the model invalid at construction time.

Source

Thrown at src/agentscope/event/_event.py:387

    """Event type."""
    reply_id: str
    """ID of the reply message this tool result belongs to."""
    tool_call_id: str
    """ID of the corresponding tool call."""
    block_id: str = Field(default_factory=_generate_id)
    """Unique identifier of the data block created by this event."""
    media_type: str
    """MIME type of the binary content."""
    data: str | None = None
    """Base64-encoded binary data, mutually exclusive with `url`."""
    url: str | None = None
    """URL pointing to the binary content, mutually exclusive with `data`."""

    @model_validator(mode="after")
    def validate_data_source(self) -> Self:
        """Ensure exactly one data source is provided."""
        if (self.data is None) == (self.url is None):
            raise ValueError(
                "Exactly one of `data` or `url` must be provided.",
            )
        return self


class ToolResultEndEvent(EventBase):
    """Tool result end event."""

    model_config = ConfigDict(use_enum_values=True)

    type: Literal[EventType.TOOL_RESULT_END] = EventType.TOOL_RESULT_END
    """Event type."""
    reply_id: str
    """ID of the reply message this tool result belongs to."""
    tool_call_id: str
    """ID of the corresponding tool call."""
    state: ToolResultState
    """Final execution state of the tool call."""

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Set exactly one field; for the other, omit it entirely rather than passing None explicitly
  2. Sanitize kwargs before construction: drop keys whose value is None
  3. If you intended inline bytes plus metadata, put metadata in a different field, not url

Example fix

# before
ev = EventBaseSubclass(data=None, url="https://example.com/x.png")  # both None-ness mismatch? no: data None + url set is OK
# actual failing cases:
ev = Event(data=b"...", url="https://...")   # both set
ev = Event()                                  # neither set

# after
ev = Event(url="https://example.com/x.png")   # exactly one
Defensive patterns

Strategy: validation

Validate before calling

payload = {k: v for k, v in (("data", data), ("url", url)) if v is not None}
assert len(payload) == 1, "provide exactly one of data/url"

Type guard

def is_valid_source_pair(data, url) -> bool:
    return (data is None) != (url is None)

Try / catch

try:
    ev = Event(data=data, url=url)
except ValueError as e:
    if "Exactly one of" in str(e):
        ev = Event(url=url) if url else Event(data=data)
    else:
        raise

Prevention

When it happens

Trigger: Constructing the event with neither data nor url, or with both populated: Event(data=raw, url="https://..."). The (data is None) == (url is None) check rejects either case during model validation.

Common situations: Conditionally building kwargs and accidentally passing data=None alongside a url (or url="" which is not None); copy/pasting event payloads; LLM-generated tool results that fill both fields.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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