{"record":{"id":"57bb7e4d8434f9b3","repo":"yikart/AiToEarn","slug":"no-image-generated","errorCode":null,"errorMessage":"No image generated","messagePattern":"No image generated","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/gemini/gemini.service.ts","lineNumber":98,"sourceCode":"        },\n      })\n\n      const images: GeminiGeneratedImage[] = []\n\n      if (response.candidates?.[0]?.content?.parts) {\n        for (const part of response.candidates[0].content.parts) {\n          if ('inlineData' in part && part.inlineData) {\n            images.push({\n              imageData: Buffer.from(part.inlineData.data!, 'base64'),\n              mimeType: part.inlineData.mimeType || 'image/png',\n            })\n          }\n        }\n      }\n\n      if (images.length === 0) {\n        this.logger.error('No image generated from Gemini API')\n        throw new Error('No image generated')\n      }\n\n      const usage: GeminiImageUsage | undefined = response.usageMetadata\n        ? {\n            promptTokenCount: response.usageMetadata.promptTokenCount || 0,\n            candidatesTokenCount: response.usageMetadata.candidatesTokenCount || 0,\n            totalTokenCount: response.usageMetadata.totalTokenCount || 0,\n            inputTokenDetails: this.extractGeminiModalityTokenDetails(response.usageMetadata['promptTokensDetails'] || []),\n            outputTokenDetails: this.extractGeminiModalityTokenDetails(response.usageMetadata['candidatesTokensDetails'] || []),\n          }\n        : undefined\n\n      this.logger.debug({\n        imageCount: images.length,\n        totalSize: images.reduce((sum, img) => sum + img.imageData.length, 0),\n        usage,\n      }, 'Image generation completed')\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/gemini/gemini.service.ts#L80-L116","documentation":"generateImage inspects the Gemini API response for inline image parts and collects them into an images array. If the response contains zero images (text-only reply, blocked/filtered content, or an unexpected response shape) it logs 'No image generated from Gemini API' and throws a plain Error('No image generated'). This signals the model ran but produced no image data.","triggerScenarios":"Gemini returns only text parts (prompt didn't elicit an image), safety filters removed the candidate content, response finishReason indicates a block, or the response structure changed so the inlineData extraction loop matches nothing.","commonSituations":"Prompts triggering safety blocking (people, brands, violence); using a non-image-capable Gemini model variant; model degraded to text-only output; API version drift changing the parts shape.","solutions":["Inspect the full Gemini response (candidates, finishReason, promptFeedback.blockReason) to see why no image came back","Rephrase the prompt to avoid safety filter triggers","Confirm the configured model is an image-generation-capable variant (e.g. gemini-*-image-*)","Catch this error upstream and surface a user-facing 'content blocked / no image' message instead of retrying blindly","Pin/verify the SDK and API version so inlineData parts parsing matches the actual response schema"],"exampleFix":"// before\nconst result = await geminiService.generateImage({ prompt: rawUserText })\n// after\ntry {\n  const result = await geminiService.generateImage({ prompt: sanitize(rawUserText) })\n} catch (e) {\n  if (e.message === 'No image generated') {\n    throw new BadRequestException('Image generation was blocked or produced no image; try a different prompt')\n  }\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"const BLOCKED_HINTS = [/(real )?person/i, /celebrit/i, /brand logo/i]\nif (BLOCKED_HINTS.some(r => r.test(prompt))) console.warn('prompt may trigger Gemini safety filter and yield no image')","typeGuard":"function isNoImageError(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'No image generated'\n}","tryCatchPattern":"try {\n  const img = await geminiService.generateImage(req)\n} catch (e) {\n  if (isNoImageError(e)) {\n    throw new BadRequestException('Gemini returned no image (likely safety-blocked or text-only). Adjust the prompt and retry.')\n  }\n  throw e\n}","preventionTips":["Use image-capable Gemini model variants only","Sanitize prompts to reduce safety-filter trips","Log the full Gemini response (finishReason, blockReason) alongside this error","Treat it as non-retryable with the same prompt; retry only after prompt changes"],"tags":["gemini","ai","empty-response"],"backgroundTag":"no-image-generated","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}