{"record":{"id":"32ef69c899853482","repo":"linshenkx/prompt-optimizer","slug":"generation-failed-32ef69","errorCode":"GENERATION_FAILED","errorMessage":"Gemini API error: ${details}","messagePattern":"Gemini API error: (.+?)","errorType":"error_code","errorClass":"ImageError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/image/adapters/gemini.ts","lineNumber":273,"sourceCode":"\n      return {\n        images: resultImages,\n        text: responseText,\n        metadata: {\n          providerId: 'gemini',\n          modelId: config.modelId,\n          configId: config.id,\n          finishReason: candidate.finishReason,\n          usage: response.usageMetadata\n        }\n      }\n    } catch (error) {\n      if (error instanceof ImageError) {\n        throw error\n      }\n\n      const details = error instanceof Error ? error.message : String(error)\n      throw new ImageError(IMAGE_ERROR_CODES.GENERATION_FAILED, `Gemini API error: ${details}`)\n    }\n  }\n}\n","sourceCodeStart":255,"sourceCodeEnd":277,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/image/adapters/gemini.ts#L255-L277","documentation":"Wraps any non-ImageError thrown during a Gemini image generation call into a GENERATION_FAILED ImageError, prefixing the underlying message with 'Gemini API error:'. It is a catch-all for network failures, HTTP errors, JSON parse errors, or SDK exceptions escaping the request path in the Gemini adapter's doGenerate.","triggerScenarios":"Calling generate() on the Gemini image adapter when the fetch to the Gemini API fails (network down, invalid API key returning an error status, malformed response body, quota exceeded) or when any unexpected runtime error occurs inside the Gemini request/response handling.","commonSituations":"Misconfigured GEMINI/GOOGLE API key, hitting free-tier rate limits, region restrictions on Gemini API, transient network outages, or Gemini API schema changes causing response parsing to throw.","solutions":["Check the embedded details message — it usually contains the underlying HTTP status or network error text","Verify the API key and endpoint configuration for the Gemini image model","Retry with exponential backoff for transient network/429 errors","If the details mention quota, inspect billing/quota for the Google Cloud project"],"exampleFix":"// before\nconst result = await geminiAdapter.generate(request, config)\n\n// after\ntry {\n  const result = await geminiAdapter.generate(request, config)\n} catch (e) {\n  if (e instanceof ImageError && e.code === IMAGE_ERROR_CODES.GENERATION_FAILED) {\n    console.error('Gemini failure:', e.message) // inspect details after prefix\n  }\n  throw e\n}","handlingStrategy":"retry","validationCode":"if (!config.apiKey) throw new Error('Gemini API key required')\nif (!request.prompt?.trim()) throw new Error('prompt required')","typeGuard":"function isImageError(e: unknown): e is ImageError {\n  return e instanceof ImageError && e.code === IMAGE_ERROR_CODES.GENERATION_FAILED\n}","tryCatchPattern":"try {\n  const r = await adapter.generate(req, config)\n} catch (e) {\n  if (isImageError(e)) {\n    const detail = e.message.replace('Gemini API error: ', '')\n    if (/429|quota/i.test(detail)) await sleep(backoff++) // retryable\n    else throw e\n  } else throw e\n}","preventionTips":["Keep the Gemini API key in config validated at startup","Wrap generation calls in retry-with-backoff for 429/5xx details","Log the unwrapped detail message to classify failures"],"tags":["gemini","image-generation","api-error","network"],"backgroundTag":"image-generation-api-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}