nexu-io/open-design · error · Error
leonardo.ai poll ${pollResp.status}
Error message
leonardo.ai poll ${pollResp.status} What it means
Thrown inside the Leonardo polling loop when GET {baseUrl}/generations/{generationId} returns a non-2xx status. The message reports only the HTTP status code (no body). Distinct from [468] (FAILED status) and [469] (timeout): this fires on transport/auth-level rejection of the poll request itself.
Source
Thrown at apps/daemon/src/media/index.ts:2265
}
// Poll for completion
const maxPollMs = 120000; // 2 minutes
const pollIntervalMs = 2000; // 2 seconds
const startedAt = Date.now();
let imageUrl: string | null = null;
while (Date.now() - startedAt < maxPollMs) {
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
const pollResp = await fetch(`${baseUrl}/generations/${generationId}`, withMediaRequestInit(ctx, {
headers: {
'authorization': `Bearer ${credentials.apiKey}`,
},
}));
if (!pollResp.ok) {
throw new Error(`leonardo.ai poll ${pollResp.status}`);
}
const pollData = (await pollResp.json()) as Record<string, any>;
const generation = pollData?.generations_by_pk;
if (generation?.status === 'COMPLETE') {
const images = generation?.generated_images;
if (Array.isArray(images) && images.length > 0) {
imageUrl = images[0]?.url;
break;
}
} else if (generation?.status === 'FAILED') {
throw new Error('leonardo.ai generation failed');
}
}
if (!imageUrl) {
throw new Error('leonardo.ai generation timed out after 2 minutes');View on GitHub (pinned to 5be4028344)
Solutions
- Retry the entire generation — transient 5xx and 429 on polls usually resolve on a fresh submit.
- If 401/403: the key was likely invalidated mid-job; refresh LEONARDO_API_KEY and resubmit.
- If 404: the generationId is gone — the job was purged or never durably created; resubmit and confirm the submit step returned a real id.
- If 429 persists: increase pollIntervalMs (currently 2000ms) for your deployment to back off.
Example fix
// before — single poll attempt throws on any non-2xx
if (!pollResp.ok) {
throw new Error(`leonardo.ai poll ${pollResp.status}`);
}
// after — tolerate transient 5xx/429 inside the poll window
if (!pollResp.ok) {
if ((pollResp.status === 429 || pollResp.status >= 500) && Date.now() - startedAt < maxPollMs) {
await new Promise(r => setTimeout(r, 5000));
continue;
}
throw new Error(`leonardo.ai poll ${pollResp.status}`);
} Defensive patterns
Strategy: retry
Try / catch
// Poll failures are dominated by transient 5xx/429; tolerate them inside the
// poll window, only throw on auth or definitive not-found.
while (Date.now() - startedAt < maxPollMs) {
await new Promise(r => setTimeout(r, pollIntervalMs));
let pollResp: Response;
try {
pollResp = await fetch(`${baseUrl}/generations/${generationId}`, withMediaRequestInit(ctx, { headers: { authorization: `Bearer ${credentials.apiKey}` } }));
} catch (e) { throw new Error(`leonardo.ai poll network error: ${String(e)}`); }
if (!pollResp.ok) {
if ((pollResp.status === 429 || pollResp.status >= 500) && Date.now() - startedAt < maxPollMs) continue;
throw new Error(`leonardo.ai poll ${pollResp.status}`);
}
// ... handle pollData
} Prevention
- Treat poll 5xx and 429 as retryable inside the ceiling rather than terminal; the current code throws on every non-2xx.
- Use a jittered backoff on 429 to avoid thundering-herd against Leonardo's rate limiter.
- Track per-generationId poll status codes in logs to detect chronic 4xx that signals key revocation mid-job.
When it happens
Trigger: Polling loop calls /generations/{id} and pollResp.ok is false — 401/403 (key lost scope mid-job), 404 (generationId doesn't exist or was purged), 429 (poll rate-limit), or 5xx (Leonardo outage).
Common situations: Polling too aggressively hitting Leonardo rate limits; generationId expired from Leonardo's retention window before completion; API key rotated mid-job; transient Leonardo 5xx during a poll window.
Related errors
- grok poll ${pollResp.status}: ${truncate(pollText, 240)}
- leonardo.ai submit ${submitResp.status}: ${truncate(submitTe
- leonardo.ai image fetch ${imgResp.status}
- petshare list page ${page} failed: ${resp.status} ${resp.sta
- hatchery list failed: ${resp.status} ${resp.statusText}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/b81ba9b0e68adb33.
Report an issue: GitHub.