invoke-ai/InvokeAI · error · ExternalProviderRequestError

Gemini returned fileUri instead of inline image data: {file_

Error message

Gemini returned fileUri instead of inline image data: {file_uri}

What it means

ExternalProviderRequestError raised when a Gemini response part contains fileData/file_uri (a Files API URI) instead of inline_data with base64 bytes. The provider only supports inline image payloads; it deliberately fails fast rather than silently dropping the image, because fetching the fileUri would require additional Files API calls and credentials. This indicates the model (or a proxy) returned the generated image as a file reference.

Source

Thrown at invokeai/app/services/external_generation/providers/gemini.py:154

            finish_message = candidate.get("finishMessage")
            finish_reason = candidate.get("finishReason")
            if isinstance(finish_message, str):
                finish_messages.append(finish_message)
            elif isinstance(finish_reason, str):
                finish_messages.append(f"Finish reason: {finish_reason}")
            for part in _iter_response_parts(candidate):
                inline_data = part.get("inline_data") or part.get("inlineData")
                if isinstance(inline_data, dict):
                    encoded = inline_data.get("data")
                    if encoded:
                        image = decode_image_base64(encoded)
                        images.append(ExternalGeneratedImage(image=image, seed=request.seed))
                        continue
                file_data = part.get("fileData") or part.get("file_data")
                if isinstance(file_data, dict):
                    file_uri = file_data.get("fileUri") or file_data.get("file_uri")
                    if isinstance(file_uri, str) and file_uri:
                        raise ExternalProviderRequestError(
                            f"Gemini returned fileUri instead of inline image data: {file_uri}"
                        )
                text = part.get("text")
                if isinstance(text, str):
                    text_parts.append(text)

        if not images:
            self._logger.error("Gemini response contained no images: %s", data)
            detail = ""
            if finish_messages:
                combined = " ".join(message.strip() for message in finish_messages if message.strip())
                if combined:
                    detail = f" Response status: {combined[:500]}"
            elif text_parts:
                combined = " ".join(text_parts).strip()
                if combined:
                    detail = f" Response text: {combined[:500]}"
            raise ExternalProviderRequestError(f"Gemini response contained no images.{detail}")

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Pin/request the Gemini model version that returns inlineData (and keep using responseModalities: ["IMAGE"] with the documented v1beta endpoint the provider targets).
  2. Bypass any proxy/gateway that rewrites the Gemini response to file references.
  3. As a provider-side fix, add code to download fileUri via the Files API (with the same API key) and inline it before decoding.
  4. Check the model id in provider_model_id matches an image model that supports inline responses.

Example fix

// before: provider-side hard failure on fileData
raise ExternalProviderRequestError(f"Gemini returned fileUri instead of inline image data: {file_uri}")
// after: fetch the file and inline it
if isinstance(file_uri, str) and file_uri:
    file_resp = requests.get(file_uri, params={"key": api_key}, timeout=60)
    file_resp.raise_for_status()
    image = decode_image_bytes(file_resp.content)
    images.append(ExternalGeneratedImage(image=image, seed=request.seed))
    continue
Defensive patterns

Strategy: fallback

Type guard

def part_is_inline_image(part: dict) -> bool:
    inline = part.get("inline_data") or part.get("inlineData")
    return isinstance(inline, dict) and bool(inline.get("data"))

def part_is_file_ref(part: dict) -> bool:
    fd = part.get("fileData") or part.get("file_data")
    return isinstance(fd, dict) and bool(fd.get("fileUri") or fd.get("file_uri"))

Try / catch

try:
    result = provider.generate(request)
except ExternalProviderRequestError as e:
    if "fileUri instead of inline" in str(e):
        file_uri = extract_uri(str(e))
        image = download_files_api_image(file_uri, api_key)  # manual fetch fallback
        result = build_result_from(image)
    else:
        raise

Prevention

When it happens

Trigger: A candidate part has fileData.fileUri (or file_data.file_uri) set — seen when using Gemini image models configured to return Files-API output, or an upstream/proxy converting inline data to file references (e.g. long-running batch responses or certain API versions returning media as fileUri).

Common situations: Using a newer Gemini image model or API surface whose default response mode stores output in the Files API; running behind a proxy that rewrites inlineData to fileData; model route (v1 vs v1beta) differences in output encoding.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/8e1bf15a56e7bf16. Report an issue: GitHub.