HKUDS/DeepTutor · error · GenerationProviderError
Image response had no image in the assistant message.
Error message
Image response had no image in the assistant message.
What it means
_extract_sources walked the assistant message content parts but found none whose image_url.url / url started with data:image or http, so the sources list is empty. This fires even though the response contained a message — the message simply had no recognizable inline image.
Source
Thrown at deeptutor/services/imagegen/adapters/chat_completions.py:96
for choice in choices or []:
message = (choice or {}).get("message") or {}
for image in message.get("images") or []:
if not isinstance(image, dict):
continue
src = (image.get("image_url") or {}).get("url") or image.get("url")
if isinstance(src, str) and src:
sources.append(src)
# Fallback: some variants nest images in the content parts array.
content = message.get("content")
if isinstance(content, list):
for part in content:
if not isinstance(part, dict):
continue
src = (part.get("image_url") or {}).get("url") or part.get("url")
if isinstance(src, str) and src.startswith(("data:image", "http")):
sources.append(src)
if not sources:
raise GenerationProviderError("Image response had no image in the assistant message.")
return sources
async def _materialize(self, client: httpx.AsyncClient, src: str) -> tuple[bytes, str]:
if src.startswith("data:"):
header, _, encoded = src.partition(",")
if not encoded:
raise GenerationProviderError("Malformed image data URI.")
content_type = header[5:].split(";", 1)[0].strip() or "image/png"
return base64.b64decode(encoded), content_type
resp = await client.get(src)
raise_for_provider(resp, "Image download")
content_type = resp.headers.get("content-type") or "image/png"
if not content_type.startswith("image/"):
content_type = "image/png"
return resp.content, content_type
__all__ = ["ChatCompletionsImagegenAdapter"]View on GitHub (pinned to 3e82f13042)
Solutions
- Log the raw response JSON and identify where the image reference actually lives
- If the field differs, normalize upstream or use a provider/adapter matching the response shape (e.g. the /images/generations adapter)
- Ensure the model actually emitted an image and not a text refusal
Defensive patterns
Strategy: try-catch
Type guard
def has_recognized_image_source(part: dict) -> bool:
src = (part.get("image_url") or {}).get("url") or part.get("url")
return isinstance(src, str) and src.startswith(("data:image", "http")) Try / catch
try:
sources = adapter._extract_sources(resp)
except GenerationProviderError:
logger.warning("unrecognized image shape: %s", resp.json())
raise Prevention
- Log raw responses from new providers before trusting the adapter
- Verify provider compatibility with the OpenAI multimodal content-part schema
When it happens
Trigger: The model returns images as markdown links, a different field name, or a URL scheme not starting with http/data:image; content parts exist but are text-only; the provider wraps image data in a proprietary shape.
Common situations: Non-OpenAI-compatible gateways returning vendor-specific image fields; model returning a relative URL or non-image content type; response shape drift after a provider API version change.
Related errors
- Chat model returned no image. Check the model supports image
- Image provider returned no images.
- Image response had no `data` array.
- Image item had neither `b64_json` nor `url`.
- DashScope response missing `output` (request_id={getattr(res
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/fcda2c358daea6de.
Report an issue: GitHub.