CherryHQ/cherry-studio · error · DashScopeTaskFailedError
DashScope task ${status.toLowerCase()}
Error message
DashScope task ${status.toLowerCase()} What it means
Thrown as a `DashScopeTaskFailedError` during polling when `task_status` is `FAILED`, `CANCELED`, or `UNKNOWN`. The message is the vendor-provided `output.message` if present, otherwise a generic `DashScope task {status}`. This is a terminal condition — the remote async task will never produce images.
Source
Thrown at src/main/ai/provider/custom/dashscope/dashscopeTransport.ts:467
let attempts = 0
let transientRetries = 0
const startTime = Date.now()
while (attempts < maxAttempts) {
if (signal?.aborted) throw createAbortError('Task polling aborted')
try {
const result = await this.request<DashScopeTaskResult>(
`/api/v1/tasks/${encodeURIComponent(taskId)}`,
'GET',
undefined,
{ timeout: 10000, signal }
)
transientRetries = 0
const status = result.output.task_status
if (status === 'SUCCEEDED') return result
if (status === 'FAILED' || status === 'CANCELED' || status === 'UNKNOWN') {
throw new DashScopeTaskFailedError(result.output.message || `DashScope task ${status.toLowerCase()}`)
}
} catch (error) {
if (signal?.aborted || (error instanceof Error && error.name === 'AbortError')) {
throw createAbortError('Task polling aborted')
}
// A terminal vendor failure or a 4xx (bar 429) poll response ends the
// loop; 5xx / 429 fall through to transient retry.
if (error instanceof DashScopeTaskFailedError) throw error
if (error instanceof DashScopeApiError && isTerminalHttpStatus(error.statusCode)) throw error
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)
continueView on GitHub (pinned to 726446b54c)
Solutions
- Inspect the error message (vendor `output.message`) for the specific rejection reason and adjust the prompt/parameters accordingly.
- Retry the generation — content-moderation and some quota failures are per-request.
- Verify account quota/billing status in the DashScope (Bailian) console.
Defensive patterns
Strategy: try-catch
Type guard
const isDashScopeTaskFailedError = (e: unknown): e is DashScopeTaskFailedError => e instanceof Error && e.name === 'DashScopeTaskFailedError'
Try / catch
try {
urls = await transport.poll(taskId, { signal })
} catch (e) {
if (e instanceof DashScopeTaskFailedError) {
// terminal vendor failure — surface e.message (vendor reason) to the user; do not retry blindly
throw new Error(`Image generation failed: ${e.message}`)
}
throw e
} Prevention
- Surface the vendor message to the user so they can adjust the prompt
- Retry once for content-moderation edge cases but don't loop on repeated failures
- Check account quota before retrying quota-related failures
When it happens
Trigger: The async image task ended in a non-success terminal state: content-moderation rejection, invalid generation parameters, quota/billing exhaustion, or an explicit vendor-side cancellation.
Common situations: Prompt or input image tripped DashScope's content filter; the account hit a concurrency/quota limit; unsupported parameter combination for the model; transient vendor outage marked the task UNKNOWN.
Related errors
- result.message || 'Task failed'
- Task polling timeout
- 0
- Task polling timeout
- Rerank response must contain a results array
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/aba1d5d6e6c8e6f0.
Report an issue: GitHub.