agentscope-ai/agentscope · error · ValueError
Gemini embedding API requires inline data (Base64Source). UR
Error message
Gemini embedding API requires inline data (Base64Source). URLSource is not directly supported for embedding. Got URL: {source.url} What it means
Gemini's embed_content API only accepts inline (base64) content, so the wrapper rejects DataBlocks whose source is a URLSource. The message is deliberate: the SDK has no from_url path for embeddings, so callers must inline the bytes themselves.
Source
Thrown at src/agentscope/embedding/_gemini/_model.py:476
"""
from google.genai import types
from ...message import Base64Source, URLSource
source = block.source
if isinstance(source, Base64Source):
import base64
return types.Part.from_bytes(
data=base64.b64decode(source.data),
mime_type=source.media_type,
)
if isinstance(source, URLSource):
# Gemini SDK doesn't have a direct from_url for
# embed_content; download or use File API.
# For now, raise — callers should use Base64Source.
raise ValueError(
"Gemini embedding API requires inline data "
"(Base64Source). URLSource is not directly supported "
f"for embedding. Got URL: {source.url}",
)
raise ValueError(
f"Unsupported source type {type(source).__name__} "
f"in DataBlock.",
)
View on GitHub (pinned to e90f1c7592)
Solutions
- Download the URL content and rebuild the DataBlock with Base64Source (inline bytes)
- Migrate assets to the Gemini File API and reference them where supported, or pre-cache bytes locally
- Centralize a to_base64_block(url) helper so URL blocks never reach the embedding model
Example fix
# before block = DataBlock(source=URLSource(url=img_url, media_type="image/png")) emb = await model(inputs=[block]) # after import requests, base64 from agentscope.message import DataBlock, Base64Source raw = requests.get(img_url, timeout=30).content block = DataBlock(source=Base64Source(data=base64.b64encode(raw).decode(), media_type="image/png")) emb = await model(inputs=[block])
Defensive patterns
Strategy: fallback
Validate before calling
from agentscope.message import URLSource
for x in inputs:
src = getattr(x, "source", None)
if isinstance(src, URLSource):
raise ValueError("inline URL blocks before calling gemini embedding") # or convert Type guard
from agentscope.message import URLSource
def has_url_source(inputs: list) -> bool:
return any(isinstance(getattr(x, "source", None), URLSource) for x in inputs) Try / catch
try:
emb = await model(inputs=inputs)
except ValueError as e:
if "URLSource is not directly supported" in str(e):
inputs = [inline_url_block(x) if is_url_block(x) else x for x in inputs]
emb = await model(inputs=inputs)
else:
raise Prevention
- Convert remote assets to Base64Source before embedding
- Keep a shared inline_url(url) helper in your codebase
- Remember chat formatters fetch URLs but the embedding API cannot
When it happens
Trigger: Building DataBlock(source=URLSource(url="https://...", media_type="image/png")) and passing it to the Gemini embedding model; _call_multimodal -> _data_block_to_part hits the URLSource branch and raises.
Common situations: Reusing URL-based DataBlocks built for chat/LLM formatters (which do fetch URLs) in an embedding call; storing assets in cloud storage (S3/GCS signed URLs) and trying to embed them directly.
Related errors
- Invalid input: {item!r}. Expected str or DataBlock.
- Invalid input: {item!r}. Expected str or DataBlock.
- DashScope multimodal embedding API error: {res}
- Multimodal embedding API only supports URL input for video d
- Unsupported media type {media_type!r} in DataBlock. Expected
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/f59e310ad40cec73.
Report an issue: GitHub.