moeru-ai/airi · error · Error

Image generation timed out after 5 minutes.

Error message

Image generation timed out after 5 minutes.

What it means

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.

Source

Thrown at apps/stage-tamagotchi/src/main/services/airi/widgets/artistry-bridge.ts:196

        internalJobId: createRunId('headless'),
      },
    }

    log.log(`[Headless] Starting generation with provider: ${requestedProvider}, model: ${params.model || 'default'}`)
    const job = await provider.generate(request)
    log.log(`[Headless] Job created: ${job.jobId}`)

    // Polling/Wait for result
    if (!supportsJobCallback(provider)) {
      let isDone = false
      let lastStatus = await provider.getStatus(job.jobId)
      const start = Date.now()
      const timeout = 1000 * 60 * 5 // 5 minutes timeout

      while (!isDone) {
        if (Date.now() - start > timeout) {
          log.error(`[Headless] Job ${job.jobId} timed out after 5 minutes.`)
          throw new Error('Image generation timed out after 5 minutes.')
        }

        log.log(`[Headless] Polling status for job: ${job.jobId}...`)
        lastStatus = await provider.getStatus(job.jobId)
        log.log(`[Headless] Status for job ${job.jobId}: ${lastStatus.status}`)

        if (lastStatus.status === 'succeeded' || lastStatus.status === 'failed') {
          isDone = true
        }
        if (!isDone) {
          await new Promise(resolve => setTimeout(resolve, 2000))
        }
      }

      if (lastStatus.status === 'failed') {
        log.error(`[Headless] Job ${job.jobId} failed: ${lastStatus.error || 'Unknown error'}`)
        throw new Error(lastStatus.error || 'Generation failed')
      }

View on GitHub (pinned to 27111382b4)

Solutions

  1. Check the provider backend (logs/queue) to see if the job is genuinely still running or stuck.
  2. Reduce input complexity (smaller resolution, fewer steps) so generation finishes within the 5-minute window.
  3. If longer jobs are expected, increase the timeout constant and ensure the backend can actually complete them.
  4. Switch to a callback-capable provider (e.g. comfyui with setJobCallback) to avoid polling-driven timeouts.

Example fix

// before
const timeout = 1000 * 60 * 5

// after
const timeout = (artistryConfig.get()?.generationTimeoutMin ?? 5) * 1000 * 60
Defensive patterns

Strategy: retry

Try / catch

try {
  return await generateHeadless(params)
} catch (e) {
  if (/timed out after 5 minutes/.test(errorMessageFrom(e) ?? '')) {
    // optionally retry once or surface a 'still running' state
    return { error: 'Generation exceeded the 5-minute timeout' }
  }
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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'.

Understand the failure class

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/aa767eed465f62ca. Report an issue: GitHub.