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
- Set exactly one field; for the other, omit it entirely rather than passing None explicitly
- Sanitize kwargs before construction: drop keys whose value is None
- 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
- Omit the unused field instead of passing None explicitly
- Note url="" is not None and still counts as set
- Drop None-valued keys when building kwargs dynamically
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
- The injection template must contain the '{runtime_state}' pl
- MCPClient name '{self.name}' contains characters not allowed
- Invalid structured output from model {model_name}: {e}
- Either client_gen or session must be provided, but not both.
- Invalid logging level: {level}. Must be one of 'INFO', 'DEBU
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/98ed2aa82c8d8a73.
Report an issue: GitHub.