CherryHQ/cherry-studio · error · Error
Task polling timeout
Error message
Task polling timeout
What it means
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.
Source
Thrown at src/main/ai/provider/custom/ppio/ppioTransport.ts:472
transientRetries++
if (transientRetries >= maxTransientRetries) {
throw error instanceof Error ? error : new Error(String(error))
}
const elapsedTime = Date.now() - startTime
const pollDelay = interval ?? (elapsedTime < 60000 ? 3000 : 10000)
await waitWithSignal(pollDelay, signal)
continue
}
const elapsedTime = Date.now() - startTime
const pollDelay = interval ?? (elapsedTime < 60000 ? 3000 : 10000)
await waitWithSignal(pollDelay, signal)
attempts++
}
throw new Error('Task polling timeout')
}
}
export function createPpioTransport(settings: PpioTransportSettings): PpioTransport {
return new PpioTransport(settings)
}
export type { PpioTransport }
View on GitHub (pinned to 726446b54c)
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.
Example fix
// before
const r = await transport.poll(taskId, { signal })
// after — extend budget for slow models
const r = await transport.poll(taskId, { signal, maxAttempts: 240, interval: 5000 }) Defensive patterns
Strategy: retry
Validate before calling
// Budget the poll loop for slow models
const maxAttempts = slowModel ? 240 : 120
const r = await transport.poll(taskId, { signal, maxAttempts, interval: 5000 }) Type guard
export function isPpioPollingTimeout(e: unknown): boolean {
return e instanceof Error && e.message === 'Task polling timeout'
} Try / catch
try {
await pollUntilDone(transport, taskId, ctx)
} catch (e) {
if (isPpioPollingTimeout(e)) {
// check PPIO dashboard: did it eventually finish?
return { timedOut: true }
}
throw e
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: PPIO under heavy load with long queues, a model that takes far longer than the budget, vendor-side hang, or upstream queue starvation.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- PPIO API request timeout after ${timeout / 1000}s
- Feishu app registration timed out
- Task polling timeout
- ${provider} returned a task id but does not implement pollin
- Task polling timeout
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/565348680ddfd5c7.
Report an issue: GitHub.