{"record":{"id":"ab953842f3a1efda","repo":"HKUDS/DeepTutor","slug":"image-response-had-no-data-array","errorCode":null,"errorMessage":"Image response had no `data` array.","messagePattern":"Image response had no `data` array\\.","errorType":"error_code","errorClass":"GenerationProviderError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/imagegen/adapters/openai_compat.py","lineNumber":77,"sourceCode":"                resp = await client.post(url, headers=headers, json=payload)\n                raise_for_provider(resp, \"Image generation\")\n                images = [\n                    await self._materialize(client, item) for item in self._extract_items(resp)\n                ]\n        except httpx.HTTPError as exc:\n            raise GenerationProviderError(f\"Image generation request error: {exc}\") from exc\n        if not images:\n            raise GenerationProviderError(\"Image provider returned no images.\")\n        return images\n\n    @staticmethod\n    def _extract_items(resp: httpx.Response) -> list[dict[str, Any]]:\n        data = resp.json()\n        if isinstance(data, dict):\n            items = data.get(\"data\")\n            if isinstance(items, list) and items:\n                return [item for item in items if isinstance(item, dict)]\n        raise GenerationProviderError(\"Image response had no `data` array.\")\n\n    async def _materialize(\n        self, client: httpx.AsyncClient, item: dict[str, Any]\n    ) -> tuple[bytes, str]:\n        b64 = item.get(\"b64_json\")\n        if isinstance(b64, str) and b64:\n            return base64.b64decode(b64), \"image/png\"\n        src = item.get(\"url\")\n        if isinstance(src, str) and src:\n            resp = await client.get(src)\n            raise_for_provider(resp, \"Image download\")\n            content_type = resp.headers.get(\"content-type\") or \"image/png\"\n            if not content_type.startswith(\"image/\"):\n                content_type = \"image/png\"\n            return resp.content, content_type\n        raise GenerationProviderError(\"Image item had neither `b64_json` nor `url`.\")\n\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/imagegen/adapters/openai_compat.py#L59-L95","documentation":"_extract_items parsed the response JSON but found no non-empty list under the top-level data key (either the body isn't a dict, or data is absent/empty/not a list). The OpenAI images API contract requires {\"data\": [ ... ]}.","triggerScenarios":"Provider returned an error-shaped 2xx body, a rate-limit/quota message without data, an empty data: [], or a completely different schema (e.g. wrapped in another key).","commonSituations":"OpenAI-compatible gateways that return errors with HTTP 200; exhausted quota returned as a message object; API version drift renaming the field.","solutions":["Log resp.json() to see the actual body — usually an inline error/quota message","Address the underlying cause the body reports (billing, quota, model access)","If the provider uses a different schema, point the config at a conforming endpoint or adapt the extraction"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"body = resp.json()\nassert isinstance(body, dict) and isinstance(body.get(\"data\"), list) and body[\"data\"], \"missing data array\"","typeGuard":"def is_openai_images_response(body) -> bool:\n    return isinstance(body, dict) and isinstance(body.get(\"data\"), list) and len(body[\"data\"]) > 0","tryCatchPattern":"try:\n    items = adapter._extract_items(resp)\nexcept GenerationProviderError:\n    logger.error(\"images/generations body lacked data: %s\", resp.text)\n    raise","preventionTips":["Check provider conformance to the OpenAI images schema when onboarding a gateway","Watch for 2xx bodies carrying error payloads and surface their message"],"tags":["imagegen","openai-compat","response-parsing"],"backgroundTag":"unexpected-response-schema","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}