moeru-ai/airi · error · Error
No image data returned from Nano Banana
Error message
No image data returned from Nano Banana
What it means
Thrown by the Nano Banana provider when the API response parsed successfully and contained no error, but no candidate part with inlineData.data was found. The provider searches candidates[0].content.parts for the first part with inlineData.data; if none exists, it cannot extract an image.
Source
Thrown at apps/stage-tamagotchi/src/main/services/airi/widgets/providers/nanobanana.ts:96
}),
})
const json = await response.json()
if (json.error) {
throw new Error(json.error.message || 'Nano Banana API Error')
}
// Search all parts for the first image
const responseParts = json.candidates?.[0]?.content?.parts || []
const imagePart = responseParts.find((p: any) => p.inlineData?.data)
const inlineData = imagePart?.inlineData
if (inlineData?.data) {
const dataUrl = `data:${inlineData.mimeType};base64,${inlineData.data}`
this.updateStatus(jobId, { status: 'succeeded', progress: 100, imageUrl: dataUrl })
}
else {
throw new Error('No image data returned from Nano Banana')
}
}
catch (e: any) {
log.error(`[Nano Banana] Generation failed: ${e.message}`)
this.updateStatus(jobId, { status: 'failed', error: e.message })
}
finally {
// Clean up callback and job result after completion to prevent memory leaks
setTimeout(() => {
this.callbacks.delete(jobId)
this.jobResults.delete(jobId)
}, 10000)
}
}
async getStatus(jobId: string): Promise<ArtistryJobStatus> {
return this.jobResults.get(jobId) || { status: 'queued' }
}View on GitHub (pinned to 27111382b4)
Solutions
- Log the full responseParts to see what the model actually returned (text refusal, empty, etc.).
- Adjust the prompt to request an image explicitly and avoid content that triggers a text-only refusal.
- Confirm the configured model outputs inlineData image parts (not all Gemini variants do).
- Handle a text-only response gracefully in the caller rather than treating it as a hard failure.
Defensive patterns
Strategy: validation
Validate before calling
// Inspect response parts before assuming an image
const parts = json.candidates?.[0]?.content?.parts ?? []
const hasImage = parts.some((p: any) => p.inlineData?.data)
if (!hasImage) {
// log parts to see if it's a text refusal
throw new Error('No image in Nano Banana response; model may have refused')
} Type guard
function hasInlineImage(parts: any[]): boolean {
return Array.isArray(parts) && parts.some(p => p?.inlineData?.data)
} Try / catch
try {
return await provider.generate(request)
} catch (e) {
if (/No image data returned/.test(errorMessageFrom(e) ?? '')) {
return { error: 'Nano Banana returned no image (possible refusal)' }
}
throw e
} Prevention
- Log responseParts to detect text refusals vs empty responses.
- Use a model variant confirmed to emit inlineData image parts.
- Craft prompts that clearly request image output to avoid text-only replies.
When it happens
Trigger: The API returned a valid response (no error field) but the candidates content was empty, contained only text parts, or the image was filtered/omitted — e.g. the model returned a textual refusal instead of an image, or the response shape differed from expectations.
Common situations: The model returned a safety refusal as text (no image); the requested model variant doesn't output inline image data; prompt engineering produced a non-image response; API version changed the part schema; candidates array was empty.
Related errors
- Nano Banana API Error
- Nano Banana API Key not configured
- Failed to add provider
- Failed to update provider config
- Artistry provider is disabled.
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/4a933c8c433097ea.
Report an issue: GitHub.