{"record":{"id":"aa767eed465f62ca","repo":"moeru-ai/airi","slug":"image-generation-timed-out-after-5-minutes","errorCode":null,"errorMessage":"Image generation timed out after 5 minutes.","messagePattern":"Image generation timed out after 5 minutes\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/stage-tamagotchi/src/main/services/airi/widgets/artistry-bridge.ts","lineNumber":196,"sourceCode":"        internalJobId: createRunId('headless'),\n      },\n    }\n\n    log.log(`[Headless] Starting generation with provider: ${requestedProvider}, model: ${params.model || 'default'}`)\n    const job = await provider.generate(request)\n    log.log(`[Headless] Job created: ${job.jobId}`)\n\n    // Polling/Wait for result\n    if (!supportsJobCallback(provider)) {\n      let isDone = false\n      let lastStatus = await provider.getStatus(job.jobId)\n      const start = Date.now()\n      const timeout = 1000 * 60 * 5 // 5 minutes timeout\n\n      while (!isDone) {\n        if (Date.now() - start > timeout) {\n          log.error(`[Headless] Job ${job.jobId} timed out after 5 minutes.`)\n          throw new Error('Image generation timed out after 5 minutes.')\n        }\n\n        log.log(`[Headless] Polling status for job: ${job.jobId}...`)\n        lastStatus = await provider.getStatus(job.jobId)\n        log.log(`[Headless] Status for job ${job.jobId}: ${lastStatus.status}`)\n\n        if (lastStatus.status === 'succeeded' || lastStatus.status === 'failed') {\n          isDone = true\n        }\n        if (!isDone) {\n          await new Promise(resolve => setTimeout(resolve, 2000))\n        }\n      }\n\n      if (lastStatus.status === 'failed') {\n        log.error(`[Headless] Job ${job.jobId} failed: ${lastStatus.error || 'Unknown error'}`)\n        throw new Error(lastStatus.error || 'Generation failed')\n      }","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/apps/stage-tamagotchi/src/main/services/airi/widgets/artistry-bridge.ts#L178-L214","documentation":"Thrown by generateHeadless's polling loop for providers that do not support job callbacks. The loop polls provider.getStatus every 2 seconds and enforces a 5-minute (300000 ms) hard timeout; if the job hasn't reached 'succeeded' or 'failed' within that window, this error is raised.","triggerScenarios":"A provider's getStatus never returns a terminal status within 5 minutes — the backend is overloaded, queued behind other jobs, stuck in a 'running' state, or the status endpoint is returning a non-terminal value indefinitely.","commonSituations":"GPU is busy / long queue on a remote generation backend; the provider underreports progress due to a status API bug; the model is very large and genuinely needs more than 5 minutes; a network hiccup causes getStatus to keep returning a stale 'running'.","solutions":["Check the provider backend (logs/queue) to see if the job is genuinely still running or stuck.","Reduce input complexity (smaller resolution, fewer steps) so generation finishes within the 5-minute window.","If longer jobs are expected, increase the timeout constant and ensure the backend can actually complete them.","Switch to a callback-capable provider (e.g. comfyui with setJobCallback) to avoid polling-driven timeouts."],"exampleFix":"// before\nconst timeout = 1000 * 60 * 5\n\n// after\nconst timeout = (artistryConfig.get()?.generationTimeoutMin ?? 5) * 1000 * 60","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await generateHeadless(params)\n} catch (e) {\n  if (/timed out after 5 minutes/.test(errorMessageFrom(e) ?? '')) {\n    // optionally retry once or surface a 'still running' state\n    return { error: 'Generation exceeded the 5-minute timeout' }\n  }\n  throw e\n}","preventionTips":["Make the timeout configurable so long jobs aren't hard-killed.","Prefer callback-capable providers to avoid polling-driven timeouts.","Right-size generation parameters (resolution/steps) to the timeout budget."],"tags":["artistry","timeout","polling","providers"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}