linshenkx/prompt-optimizer · error · ImageError

GENERATION_FAILED

GENERATION_FAILED

Error message

Gemini API error: ${details}

What it means

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.

Source

Thrown at packages/core/src/services/image/adapters/gemini.ts:273

      return {
        images: resultImages,
        text: responseText,
        metadata: {
          providerId: 'gemini',
          modelId: config.modelId,
          configId: config.id,
          finishReason: candidate.finishReason,
          usage: response.usageMetadata
        }
      }
    } catch (error) {
      if (error instanceof ImageError) {
        throw error
      }

      const details = error instanceof Error ? error.message : String(error)
      throw new ImageError(IMAGE_ERROR_CODES.GENERATION_FAILED, `Gemini API error: ${details}`)
    }
  }
}

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Check the embedded details message — it usually contains the underlying HTTP status or network error text
  2. Verify the API key and endpoint configuration for the Gemini image model
  3. Retry with exponential backoff for transient network/429 errors
  4. If the details mention quota, inspect billing/quota for the Google Cloud project

Example fix

// before
const result = await geminiAdapter.generate(request, config)

// after
try {
  const result = await geminiAdapter.generate(request, config)
} catch (e) {
  if (e instanceof ImageError && e.code === IMAGE_ERROR_CODES.GENERATION_FAILED) {
    console.error('Gemini failure:', e.message) // inspect details after prefix
  }
  throw e
}
Defensive patterns

Strategy: retry

Validate before calling

if (!config.apiKey) throw new Error('Gemini API key required')
if (!request.prompt?.trim()) throw new Error('prompt required')

Type guard

function isImageError(e: unknown): e is ImageError {
  return e instanceof ImageError && e.code === IMAGE_ERROR_CODES.GENERATION_FAILED
}

Try / catch

try {
  const r = await adapter.generate(req, config)
} catch (e) {
  if (isImageError(e)) {
    const detail = e.message.replace('Gemini API error: ', '')
    if (/429|quota/i.test(detail)) await sleep(backoff++) // retryable
    else throw e
  } else throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/32ef69c899853482. Report an issue: GitHub.