{"record":{"id":"565348680ddfd5c7","repo":"CherryHQ/cherry-studio","slug":"task-polling-timeout-565348","errorCode":null,"errorMessage":"Task polling timeout","messagePattern":"Task polling timeout","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/provider/custom/ppio/ppioTransport.ts","lineNumber":472,"sourceCode":"        transientRetries++\n\n        if (transientRetries >= maxTransientRetries) {\n          throw error instanceof Error ? error : new Error(String(error))\n        }\n\n        const elapsedTime = Date.now() - startTime\n        const pollDelay = interval ?? (elapsedTime < 60000 ? 3000 : 10000)\n        await waitWithSignal(pollDelay, signal)\n        continue\n      }\n\n      const elapsedTime = Date.now() - startTime\n      const pollDelay = interval ?? (elapsedTime < 60000 ? 3000 : 10000)\n      await waitWithSignal(pollDelay, signal)\n      attempts++\n    }\n\n    throw new Error('Task polling timeout')\n  }\n}\n\nexport function createPpioTransport(settings: PpioTransportSettings): PpioTransport {\n  return new PpioTransport(settings)\n}\n\nexport type { PpioTransport }\n","sourceCodeStart":454,"sourceCodeEnd":481,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/provider/custom/ppio/ppioTransport.ts#L454-L481","documentation":"Thrown at the end of PpioTransport.pollTaskResult() when the loop has exhausted maxAttempts (default 120) without the task reaching TASK_STATUS_SUCCEED or TASK_STATUS_FAILED. It is a timeout on polling cadence, not on a single HTTP call — the task simply never settled.","triggerScenarios":"The task remains in TASK_STATUS_QUEUED or TASK_STATUS_PROCESSING across all 120 poll attempts. With the adaptive 3s(<60s)/10s(>60s) interval this is roughly 12–18 minutes. Concrete causes: vendor queue backlog, hung generation, very slow large-image render, or upstream silently stuck.","commonSituations":"PPIO under heavy load with long queues, a model that takes far longer than the budget, vendor-side hang, or upstream queue starvation.","solutions":["Increase maxAttempts (or the per-task interval) when the model is known to be slow — pass a larger options.maxAttempts to pollTaskResult.","Verify with the PPIO dashboard whether the task eventually completed — if so, the budget was just too small.","Retry submit once for a genuinely stuck task; if it stalls repeatedly, report a vendor-side issue.","Surface to the user as 'generation is taking longer than expected' with a cancel/retry affordance."],"exampleFix":"// before\nconst r = await transport.poll(taskId, { signal })\n// after — extend budget for slow models\nconst r = await transport.poll(taskId, { signal, maxAttempts: 240, interval: 5000 })","handlingStrategy":"retry","validationCode":"// Budget the poll loop for slow models\nconst maxAttempts = slowModel ? 240 : 120\nconst r = await transport.poll(taskId, { signal, maxAttempts, interval: 5000 })","typeGuard":"export function isPpioPollingTimeout(e: unknown): boolean {\n  return e instanceof Error && e.message === 'Task polling timeout'\n}","tryCatchPattern":"try {\n  await pollUntilDone(transport, taskId, ctx)\n} catch (e) {\n  if (isPpioPollingTimeout(e)) {\n    // check PPIO dashboard: did it eventually finish?\n    return { timedOut: true }\n  }\n  throw e\n}","preventionTips":["Extend maxAttempts / interval for known-slow models.","Surface a 'generation taking longer than expected' message with a cancel option.","Check the PPIO dashboard before re-submitting — the task may still complete."],"tags":["ppio","timeout","polling","image-generation"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}