{"record":{"id":"e1099a942e00c61d","repo":"invoke-ai/InvokeAI","slug":"gemini-response-contained-no-images-detail","errorCode":null,"errorMessage":"Gemini response contained no images.{detail}","messagePattern":"Gemini response contained no images\\.(.+?)","errorType":"exception","errorClass":"ExternalProviderRequestError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/external_generation/providers/gemini.py","lineNumber":172,"sourceCode":"                        raise ExternalProviderRequestError(\n                            f\"Gemini returned fileUri instead of inline image data: {file_uri}\"\n                        )\n                text = part.get(\"text\")\n                if isinstance(text, str):\n                    text_parts.append(text)\n\n        if not images:\n            self._logger.error(\"Gemini response contained no images: %s\", data)\n            detail = \"\"\n            if finish_messages:\n                combined = \" \".join(message.strip() for message in finish_messages if message.strip())\n                if combined:\n                    detail = f\" Response status: {combined[:500]}\"\n            elif text_parts:\n                combined = \" \".join(text_parts).strip()\n                if combined:\n                    detail = f\" Response text: {combined[:500]}\"\n            raise ExternalProviderRequestError(f\"Gemini response contained no images.{detail}\")\n\n        return ExternalGenerationResult(\n            images=images,\n            seed_used=request.seed,\n            provider_metadata={\"model\": request.model.provider_model_id},\n        )\n\n\ndef _iter_response_parts(candidate: dict[str, object]) -> list[dict[str, object]]:\n    content = candidate.get(\"content\")\n    if isinstance(content, dict):\n        content_parts = content.get(\"parts\")\n        if isinstance(content_parts, list):\n            return [part for part in content_parts if isinstance(part, dict)]\n    contents = candidate.get(\"contents\")\n    if isinstance(contents, list):\n        parts: list[dict[str, object]] = []\n        for item in contents:","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/external_generation/providers/gemini.py#L154-L190","documentation":"ExternalProviderRequestError raised after the provider parsed all candidates and found zero decodable inline images. The message is enriched with a detail suffix: finish messages/finish reasons from candidates (e.g. 'Finish reason: SAFETY') or, if none, the model's text parts (truncated to 500 chars), so the developer can see why Gemini produced text-only or empty output despite a 200 response.","triggerScenarios":"All candidates contained only text parts (model answered with prose instead of an image), parts were skipped as non-dict, inline_data.data was empty, or candidates carried finishReason like SAFETY/RECITATION with no image payload.","commonSituations":"Prompt interpreted as a question rather than an image request; safety-filtered content with finishReason SAFETY; model overload returning degraded text-only answers; prompt asking for text output explicitly; invalid imageConfig causing silent fallback.","solutions":["Read the 'Response status'/'Response text' suffix in the message — it names the finish reason or the model's textual excuse.","If SAFETY: rephrase the prompt or remove flagged reference/init images.","If text-only: strengthen the instruction to request an image (the provider's system instruction already tries this) and avoid prompts that read as questions.","Retry — transient model degradation often resolves on a second attempt.","Try a different Gemini image model id for the workload."],"exampleFix":"// before: retrying blindly on empty output\nfor _ in range(3):\n    try:\n        return provider.generate(request)\n    except ExternalProviderRequestError:\n        pass\n// after: inspect finish reason and rephrase once if safety/text-only\ntry:\n    return provider.generate(request)\nexcept ExternalProviderRequestError as e:\n    if \"SAFETY\" in str(e):\n        request = replace_prompt(request, sanitized_prompt)\n        return provider.generate(request)\n    raise","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = provider.generate(request)\nexcept ExternalProviderRequestError as e:\n    detail = str(e)\n    if \"SAFETY\" in detail or \"RECITATION\" in detail:\n        notify_user(\"Gemini blocked this request; rephrase the prompt.\")\n    elif \"Response text:\" in detail:\n        retry_once_with_stronger_image_instruction(request)  # model answered in prose\n    else:\n        retry_once(request)  # transient empty response","preventionTips":["Parse the detail suffix — it tells you whether to rephrase (safety/text) or just retry (transient).","Write prompts that clearly request an image, not questions or explanations.","Prefer init/reference images that are policy-compliant to avoid finishReason SAFETY.","Cap retries at 1-2 to avoid burning quota on prompts the model will never fulfill."],"tags":["gemini","empty-response","safety-filter","text-only-response"],"backgroundTag":"empty-or-blocked-response","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}