moeru-ai/airi · warning

[InferenceWorkerManager] Restarting worker in ${delay}ms (at

Error message

[InferenceWorkerManager] Restarting worker in ${delay}ms (attempt ${restartAttempts}/${maxRestarts})

What it means

Scheduled-restart notice from InferenceWorkerManager, the generic lifecycle wrapper for inference Web Workers in packages/stage-ui/src/libs/inference/worker-manager.ts. When the managed worker dies or fails terminally, scheduleRestart() re-spawns it via ensureStarted() with linear backoff (restartDelayMs multiplied by attempt number; defaults 1000ms base, 3 max attempts from WorkerManagerOptions). This line is only the retry announcement - the actual crash cause appears earlier in the console or on manager.lastError.

Source

Thrown at packages/stage-ui/src/libs/inference/worker-manager.ts:207

  function destroyWorker(): void {
    if (worker) {
      worker.terminate()
      worker = null
    }
  }

  function scheduleRestart(): void {
    if (restartAttempts >= maxRestarts) {
      console.error(
        `[InferenceWorkerManager] Max restart attempts (${maxRestarts}) reached. Giving up.`,
      )
      return
    }

    restartAttempts++
    const delay = restartDelayMs * restartAttempts

    console.warn(
      `[InferenceWorkerManager] Restarting worker in ${delay}ms `
      + `(attempt ${restartAttempts}/${maxRestarts})`,
    )

    setTimeout(() => {
      ensureStarted().catch((err) => {
        console.error('[InferenceWorkerManager] Failed to restart:', errorMessageFrom(err))
      })
    }, delay)
  }

  function onSuccessfulOperation(): void {
    restartAttempts = 0
  }

  async function ensureStarted(): Promise<void> {
    await lifecycleMutex.runExclusive(async () => {
      if (!worker) {

View on GitHub (pinned to 677329427f)

Solutions

  1. Scroll up in the console for the originating worker error, or read manager.lastError - this log only reports the retry, not the cause
  2. If the log sequence ends with 'Max restart attempts reached', reproduce the worker failure directly and fix the root cause (model id, quantization, device support, import failure)
  3. Raise maxRestarts or restartDelayMs in the options passed to createInferenceWorkerManager when the crash is transient, e.g. a GPU reset during startup
  4. Reduce model size or quantization, or force device 'wasm', if the worker dies from OOM during load
  5. After the manager gives up (state 'error'), call terminate() and build a fresh manager instead of expecting automatic recovery

Example fix

// before
const manager = createInferenceWorkerManager({ createWorker })
// crash loop exhausts defaults: 3 attempts, 1s base delay

// after
const manager = createInferenceWorkerManager({
  createWorker,
  maxRestarts: 5,
  restartDelayMs: 2_000, // backoff: 2s, 4s, 6s...
})
Defensive patterns

Strategy: retry

Validate before calling

if (manager.state !== 'ready' && manager.state !== 'running') {
  await manager.loadModel({ modelId, device: 'wasm' })
}

Type guard

function isUsableManager(m: InferenceWorkerManager): boolean {
  return m.state === 'ready' || m.state === 'running'
}

Try / catch

try {
  await manager.run(input)
}
catch (err) {
  if (manager.state === 'error' || manager.state === 'terminated') {
    manager.terminate()
    // rebuild the manager, then retry the operation once
  }
  else throw err
}

Prevention

When it happens

Trigger: The worker exits unexpectedly (uncaught exception or out-of-memory inside the worker during transformers.js model load or inference), a loadModel/run request fails hard enough to trigger the restart path, or the browser tears the worker down. Each failure increments restartAttempts and logs 'Restarting worker in <delay>ms (attempt N/M)'. After maxRestarts failures the manager logs 'Max restart attempts reached. Giving up.' and stops.

Common situations: WebGPU device lost inside the worker, OOM when loading a large model, stale worker bundle after dev HMR, or a deterministic crash loop (bad model file, unsupported device, missing import) that burns all 3 attempts. Note the file header: no adapter currently consumes this manager, so seeing it means custom code built on it.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/079b3d6000e6e735. Report an issue: GitHub.