{"record":{"id":"ddfd28c915277bdc","repo":"moeru-ai/airi","slug":"kokoroadapter-restarting-in-delay-ms-attempt","errorCode":null,"errorMessage":"[KokoroAdapter] Restarting in ${delay}ms (attempt ${restartAttempts}/${MAX_RESTARTS})","messagePattern":"\\[KokoroAdapter\\] Restarting in (.+?)ms \\(attempt (.+?)/(.+?)\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/stage-ui/src/libs/inference/adapters/kokoro.ts","lineNumber":288,"sourceCode":"      worker = null\n    }\n  }\n\n  function scheduleRestart(): void {\n    if (restartAttempts >= MAX_RESTARTS) {\n      console.error(\n        `[KokoroAdapter] Max restart attempts (${MAX_RESTARTS}) reached.`,\n      )\n      // NOTICE: Transition to 'terminated' so getKokoroAdapter() can detect\n      // the dead singleton and create a fresh adapter on next access.\n      state = 'terminated'\n      return\n    }\n\n    restartAttempts++\n    const delay = RESTART_DELAY_MS * restartAttempts\n\n    console.warn(\n      `[KokoroAdapter] Restarting in ${delay}ms `\n      + `(attempt ${restartAttempts}/${MAX_RESTARTS})`,\n    )\n\n    setTimeout(() => {\n      ensureStarted().catch((err) => {\n        console.error('[KokoroAdapter] Restart failed:', err)\n      })\n    }, delay)\n  }\n\n  function onSuccess(): void {\n    restartAttempts = 0\n  }\n\n  async function ensureStarted(): Promise<void> {\n    await lifecycleMutex.runExclusive(async () => {\n      if (!worker) {","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-ui/src/libs/inference/adapters/kokoro.ts#L270-L306","documentation":"The Kokoro TTS adapter supervises a Web Worker; when the worker errors/terminates, scheduleRestart() applies linear backoff (RESTART_DELAY_MS × attempt) up to MAX_RESTARTS, logging each attempt with this warn. After the cap it logs an error and flips state to 'terminated' so getKokoroAdapter() can replace the dead singleton on next access. The warn itself is healthy self-healing, not a defect.","triggerScenarios":"Worker crash from an uncaught exception (WASM abort, OOM in transformers.js), browser killing the worker under memory pressure, or repeated failed model loads during ensureStarted().","commonSituations":"Low-memory devices loading large Kokoro quantizations; transformers.js/runtime version incompatibility; onnxruntime-web WASM SIMD unsupported so the worker aborts.","solutions":["Reproduce with the worker console open to capture the underlying error (this warn is only the retry signal).","Lower the model quantization / dtype so the worker uses less memory.","Update transformers.js / onnxruntime-web to versions compatible with your browser.","If it reached 'terminated', call getKokoroAdapter() again — it creates a fresh adapter with a fresh restart budget."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep worker restart logic bounded (as done) and always transition to 'terminated' after the cap.","Access adapters via the getter that replaces terminated singletons instead of caching the instance forever.","Capture worker-side errors to a report channel so the root cause is not lost behind the retry warn."],"tags":["kokoro","tts","web-worker","restart","backoff","inference"],"backgroundTag":"web-worker-crash","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}