decolua/9router · error
NanoBanana generation failed
Error message
NanoBanana generation failed
What it means
Thrown when the NanoBanana poll endpoint reports the generation task itself failed: the successFlag field comes back 2 or 3 (failure codes). The error message is the provider's own s.data.errorMessage when present, falling back to this generic string. Unlike [50], the HTTP call succeeded — the upstream task genuinely failed.
Source
Thrown at open-sse/handlers/imageProviders/nanobanana.js:51
}
return req;
},
// Async: parse submit → poll until SUCCESS, return raw poll data
async parseResponse(response, { headers }) {
const submitData = await response.json();
if (submitData.code !== 200) throw new Error(submitData.msg || "NanoBanana submit failed");
const taskId = submitData.data?.taskId;
if (!taskId) throw new Error("NanoBanana: no taskId returned");
const pollUrl = `${POLL_BASE}?taskId=${encodeURIComponent(taskId)}`;
const deadline = Date.now() + POLL_TIMEOUT_MS;
while (Date.now() < deadline) {
await sleep(POLL_INTERVAL_MS);
const r = await fetch(pollUrl, { headers });
if (!r.ok) throw new Error(`NanoBanana status ${r.status}`);
const s = await r.json();
const flag = s.data?.successFlag;
if (flag === 1) return s.data;
if (flag === 2 || flag === 3) throw new Error(s.data?.errorMessage || "NanoBanana generation failed");
}
throw new Error("NanoBanana polling timeout");
},
normalize: (responseBody, prompt) => {
const url = responseBody.response?.resultImageUrl || responseBody.response?.originImageUrl;
if (url) return { created: nowSec(), data: [{ url, revised_prompt: prompt }] };
return { created: nowSec(), data: [] };
},
};
View on GitHub (pinned to 90b52e06ff)
Solutions
- Log/inspect the full poll response to read s.data.errorMessage — the thrown Error already carries it when the provider supplies one.
- If the message is the generic fallback, re-run with a simpler/safer prompt to rule out moderation rejection.
- For edit requests, verify every URL in imageUrls/body.image is publicly fetchable and a supported format (png/jpeg).
- Retry once with a fresh submit — transient upstream capacity failures are common with this async API.
- Check numImages (body.n) and image_size/ratio values against the provider's supported ranges.
Example fix
// before (caller has no provider detail when errorMessage is absent)
const flag = s.data?.successFlag;
if (flag === 2 || flag === 3) throw new Error(s.data?.errorMessage || "NanoBanana generation failed");
// after
const flag = s.data?.successFlag;
if (flag === 2 || flag === 3) throw new Error(s.data?.errorMessage || `NanoBanana generation failed (successFlag=${flag}, taskId=${taskId})`); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the request before submitting to reduce upstream task failures
if (!body.prompt || !body.prompt.trim()) throw new Error("prompt is required");
const urls = [body.image, ...(Array.isArray(body.images) ? body.images : [])].filter(Boolean);
for (const u of urls) {
if (!/^https?:\/\//.test(u)) throw new Error(`image URL must be http(s): ${u}`);
} Type guard
function isPollResult(s) { return !!s && typeof s === "object" && s.data != null && typeof s.data.successFlag === "number"; }
// then: if (isPollResult(s) && (s.data.successFlag === 2 || s.data.successFlag === 3)) -> failed Try / catch
try {
const data = await imageProvider.parseResponse(response, { headers });
} catch (e) {
if (e.message === "NanoBanana generation failed" || /NanoBanana/.test(e.message)) {
console.error("NanoBanana task failed:", e.message); // e.message may carry provider errorMessage
return { error: { code: "generation_failed", detail: e.message } }; // surface to client instead of crashing
}
throw e;
} Prevention
- Pre-screen prompts for likely moderation triggers before submitting.
- For edit (image-to-image) calls, verify source image URLs are public and fetchable.
- Keep numImages and ratio within provider-supported ranges.
- Log full poll payloads so successFlag 2/3 failures can be diagnosed from provider errorMessage.
When it happens
Trigger: During polling in open-sse/handlers/imageProviders/nanobanana.js:49-51, the poll JSON satisfies `s.data?.successFlag === 2 || s.data?.successFlag === 3`. The thrown message equals `s.data?.errorMessage` when provided, otherwise the literal 'NanoBanana generation failed'.
Common situations: Prompt rejected by upstream content moderation; image edit requests (type IMAGETOIAMGE) with unreachable or rejected imageUrls; invalid numImages/ratio combos; upstream GPU capacity failures; generic 'generation failed' because the provider returns successFlag 2/3 with no errorMessage.
Related errors
- BFL: no polling_url returned
- NanoBanana status ${r.status}
- NanoBanana polling timeout
- Runway: no task id returned
- Runway status ${r.status}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/4a662a6bc3f20c91.
Report an issue: GitHub.