agentscope-ai/agentscope · error · ValueError

Invalid input: {item!r}. Expected str or DataBlock.

Error message

Invalid input: {item!r}. Expected str or DataBlock.

What it means

The Gemini multimodal embedding path only accepts two input shapes per item: plain str (text) or a DataBlock instance (image/audio/video). Anything else (dict, bytes, int, PIL image, None) fails validation before the request is built.

Source

Thrown at src/agentscope/embedding/_gemini/_model.py:416

        """
        from google.genai import types

        contents: list[types.Content] = []
        for item in inputs:
            if isinstance(item, str):
                contents.append(
                    types.Content(
                        parts=[types.Part.from_text(text=item)],
                    ),
                )
            elif isinstance(item, DataBlock):
                contents.append(
                    types.Content(
                        parts=[self._data_block_to_part(item)],
                    ),
                )
            else:
                raise ValueError(
                    f"Invalid input: {item!r}. Expected str or DataBlock.",
                )

        config = types.EmbedContentConfig(
            output_dimensionality=self.dimensions,
            **kwargs,
        )

        start_time = datetime.now()
        response = self.client.models.embed_content(
            model=self.model,
            contents=contents,
            config=config,
        )
        time = (datetime.now() - start_time).total_seconds()

        embeddings = [item.values for item in response.embeddings]

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Wrap binary/structured items in DataBlock with a proper source (Base64Source for inline data)
  2. Convert PIL images to PNG bytes and wrap in DataBlock with Base64Source and media_type
  3. Keep plain strings as-is for text parts of the batch

Example fix

# before
emb = await model(inputs=[{"type": "image", "data": png_bytes}])

# after
from agentscope.message import DataBlock, Base64Source
block = DataBlock(source=Base64Source(data=png_bytes, media_type="image/png"))
emb = await model(inputs=["describe", block])
Defensive patterns

Strategy: type-guard

Validate before calling

from agentscope.message import DataBlock
ok = all(isinstance(x, (str, DataBlock)) for x in inputs)

Type guard

from agentscope.message import DataBlock
from typing import Union

def is_valid_multimodal_input(inputs: list) -> bool:
    return all(isinstance(x, (str, DataBlock)) for x in inputs)

Try / catch

try:
    emb = await model(inputs=inputs)
except ValueError as e:
    if "Expected str or DataBlock" in str(e):
        inputs = [x if isinstance(x, (str, DataBlock)) else to_data_block(x) for x in inputs]
        emb = await model(inputs=inputs)
    else:
        raise

Prevention

When it happens

Trigger: Calling the multimodal embedding model with items like {"type": "image_url", ...} raw dicts, raw bytes, or PIL Image objects instead of DataBlock wrappers; routed through _call_api -> _call_multimodal.

Common situations: Porting code from OpenAI-style embedding APIs that take dicts; assuming bytes or PIL images are accepted; older examples passing tuples of (data, mime_type).

Related errors


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