HKUDS/DeepTutor · error · GenerationProviderError

Image item had neither `b64_json` nor `url`.

Error message

Image item had neither `b64_json` nor `url`.

What it means

_materialize inspected a data item dict and found neither a non-empty b64_json string nor a usable url field to fetch, so there is no way to obtain image bytes from that item.

Source

Thrown at deeptutor/services/imagegen/adapters/openai_compat.py:93

            if isinstance(items, list) and items:
                return [item for item in items if isinstance(item, dict)]
        raise GenerationProviderError("Image response had no `data` array.")

    async def _materialize(
        self, client: httpx.AsyncClient, item: dict[str, Any]
    ) -> tuple[bytes, str]:
        b64 = item.get("b64_json")
        if isinstance(b64, str) and b64:
            return base64.b64decode(b64), "image/png"
        src = item.get("url")
        if isinstance(src, str) and src:
            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
        raise GenerationProviderError("Image item had neither `b64_json` nor `url`.")


__all__ = ["OpenAICompatImagegenAdapter"]

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Inspect the item dict to see which fields it actually carries
  2. Set response_format in the request payload to the value your provider honors (url or b64_json)
  3. If the provider simply doesn't populate either field, switch endpoint or provider

Example fix

// before
payload = {"model": m, "prompt": p}  # provider defaults omit url/b64
// after
payload = {"model": m, "prompt": p, "response_format": "b64_json"}
Defensive patterns

Strategy: validation

Validate before calling

def item_has_image(item: dict) -> bool:
    return (isinstance(item.get("b64_json"), str) and item["b64_json"]) or isinstance(item.get("url"), str)

Type guard

def is_materializable(item) -> bool:
    return isinstance(item, dict) and (bool(item.get("b64_json")) or bool(item.get("url")))

Try / catch

try:
    img = await adapter._materialize(client, item)
except GenerationProviderError as exc:
    if "neither" in str(exc):
        continue  # skip unusable item

Prevention

When it happens

Trigger: A data item containing only extra fields (e.g. revised_prompt alone), a null/empty b64_json and no url, or response_format set to url while the provider omits url.

Common situations: Provider response_format mismatch (asking b64_json but getting url-only or vice versa), partial fields on error, schema drift in third-party gateways.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/32aeb3bcb6bb12ac. Report an issue: GitHub.