HKUDS/DeepTutor · error · GenerationProviderError

Image generation request error: {exc}

Error message

Image generation request error: {exc}

What it means

A httpx.HTTPError (connection failure, timeout, TLS error, etc.) occurred while POSTing the image-generation chat-completions request or downloading an image URL it returned. The adapter wraps the transport-level exception in GenerationProviderError, chaining the original exc.

Source

Thrown at deeptutor/services/imagegen/adapters/chat_completions.py:64

            **build_auth_headers(config.auth_style, config.api_key),
            **(config.extra_headers or {}),
        }
        payload: dict[str, Any] = {
            "model": config.model,
            "messages": [{"role": "user", "content": prompt}],
            "modalities": ["image", "text"],
        }

        logger.debug("imagegen(chat) url=%s model=%s", url, config.model)
        try:
            async with httpx.AsyncClient(timeout=config.request_timeout) as client:
                resp = await client.post(url, headers=headers, json=payload)
                raise_for_provider(resp, "Image generation")
                images = [
                    await self._materialize(client, src) for src in self._extract_sources(resp)
                ]
        except httpx.HTTPError as exc:
            raise GenerationProviderError(f"Image generation request error: {exc}") from exc
        if not images:
            raise GenerationProviderError(
                "Chat model returned no image. Check the model supports image output "
                "(its output modalities must include `image`)."
            )
        return images

    @staticmethod
    def _extract_sources(resp: httpx.Response) -> list[str]:
        """Pull image URLs / data URIs out of the assistant message."""
        data = resp.json()
        sources: list[str] = []
        choices = data.get("choices") if isinstance(data, dict) else None
        for choice in choices or []:
            message = (choice or {}).get("message") or {}
            for image in message.get("images") or []:
                if not isinstance(image, dict):
                    continue

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Verify the base_url host resolves and is reachable (curl a simple chat completion against it)
  2. Retry with backoff — transient network/timeout failures are common for long-running image generation
  3. If behind a proxy, set HTTP_PROXY/HTTPS_PROXY or configure httpx accordingly; if TLS fails on a self-hosted gateway, fix the certificate
  4. Increase the client timeout passed to the adapter so slow image models aren't cut off
Defensive patterns

Strategy: retry

Validate before calling

import socket
socket.gethostbyname(urlparse(config.base_url).hostname)  # raises early if DNS fails

Try / catch

try:
    images = await adapter.generate(prompt, config)
except GenerationProviderError as exc:
    if "request error" in str(exc):
        # httpx.HTTPError underneath; safe to retry with backoff
        await asyncio.sleep(backoff); retry()
    raise

Prevention

When it happens

Trigger: DNS resolution failure or refused connection to config.base_url; network timeout during the multimodal chat/completions call; TLS certificate error; a returned image URL that fails to download (the _materialize GET happens inside the same try block).

Common situations: Wrong/unreachable base_url, corporate proxy or firewall blocking the API host, ephemeral network outage, self-signed cert on a self-hosted OpenAI-compatible gateway, short timeout against a slow image-generating model.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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