nexu-io/open-design · error · Error

aihubmix gemini image response had no inline image data: ${J

Error message

aihubmix gemini image response had no inline image data: ${JSON.stringify(data).slice(0, 200)}

What it means

Plain Error thrown by aihubmixGeminiImageBytes when the HTTP response was OK (2xx) but the parsed JSON contains no inline image data — specifically, none of the candidate parts contain inlineData.data / inline_data.data as a non-empty string. The error echoes the first 200 chars of the JSON for debugging. This indicates the model accepted the request but returned text-only or empty content instead of an image.

Source

Thrown at apps/daemon/src/integrations/aihubmix.ts:153

    body: JSON.stringify({
      contents: [{ role: 'user', parts: [{ text: req.prompt }] }],
      generationConfig: {
        responseModalities: ['TEXT', 'IMAGE'],
        imageConfig: { aspectRatio: req.aspect },
      },
    }),
  });
  if (!resp.ok) {
    const text = await resp.text().catch(() => '');
    throw new Error(`aihubmix image (gemini) ${resp.status}: ${text.slice(0, 240)}`);
  }
  const data = (await resp.json()) as any;
  const parts: any[] = data?.candidates?.[0]?.content?.parts ?? [];
  const b64 = parts
    .map((p) => p?.inlineData?.data || p?.inline_data?.data)
    .find((d) => typeof d === 'string' && d);
  if (!b64) {
    throw new Error(
      `aihubmix gemini image response had no inline image data: ${JSON.stringify(data).slice(0, 200)}`,
    );
  }
  return Buffer.from(b64, 'base64');
}

// Catalogue ids vs wire names. The media registry requires globally-unique
// model ids, but `gpt-image-1` / `dall-e-3` / `tts-1` are already owned by the
// `openai` provider. So AIHubMix's models are registered with an `aihubmix-`
// prefix and mapped back to the real upstream name here. A plain prefix strip
// is the fallback so adding a new `aihubmix-<wire>` entry needs no edit here.
const AIHUBMIX_WIRE_MODELS: Record<string, string> = {
  'aihubmix-gpt-image-1': 'gpt-image-1',
  'aihubmix-dall-e-3': 'dall-e-3',
  'aihubmix-tts-1': 'tts-1',
};

export function aihubmixWireModel(catalogId: string): string {

View on GitHub (pinned to 5be4028344)

Solutions

  1. Inspect the interpolated JSON (first 200 chars) — a safety refusal is usually visible as text content.
  2. Rephrase the prompt to avoid flagged content; try a different aspectRatio.
  3. Confirm the wireModel actually supports image output (some gemini variants are text-only).
  4. Verify generationConfig.responseModalities includes IMAGE and the model honors it.
  5. If the JSON shape looks valid but image data is under a different key, the parser may need updating — file an issue with the response shape.
Defensive patterns

Strategy: validation

Validate before calling

function hasInlineImage(data: unknown): boolean {
  const parts = (data as any)?.candidates?.[0]?.content?.parts ?? [];
  return parts.some((p: any) =>
    typeof (p?.inlineData?.data ?? p?.inline_data?.data) === 'string'
    && (p.inlineData?.data ?? p.inline_data?.data).length > 0);
}

Try / catch

try {
  return await aihubmixGeminiImageBytes(req, doFetch);
} catch (err) {
  if (err instanceof Error && /no inline image data/.test(err.message)) {
    // 200 but text-only response — usually a safety refusal or wrong model
    throw new ImageGenerationRefusedError('Model returned no image (possible safety filter or text-only model)');
  }
  throw err;
}

Prevention

When it happens

Trigger: The gemini/imagen model returned 200 with only text parts (e.g. a safety refusal, a 'cannot generate' message, or a text explanation); responseModalities did not include IMAGE on the upstream side; the model safety filter blocked the prompt and returned text instead; AIHubMix stripped the image data; an unexpected response schema variant where image data lives under a different key.

Common situations: Prompt tripped Gemini's safety filters (returns text refusal with 200); model is text-only despite being routed here; aspectRatio/prompt combination the model declined; AIHubMix passed through a text-only response from an upstream error; a model that requires a different image-output configuration.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/7db8cfa5b81922fa. Report an issue: GitHub.