CherryHQ/cherry-studio · error · DashScopeApiError
DashScope API error: ${response.status} - ${errorText}
Error message
DashScope API error: ${response.status} - ${errorText} What it means
Thrown as a `DashScopeApiError` when a fetch to DashScope returns a non-2xx HTTP status. The message includes the status code and the first 500 characters of the response body; the `statusCode` field carries the numeric HTTP status for programmatic handling. This covers auth, quota, validation, and server errors at the transport boundary.
Source
Thrown at src/main/ai/provider/custom/dashscope/dashscopeTransport.ts:537
const fetchOptions: RequestInit = {
method,
headers: {
Authorization: `Bearer ${this.apiKey}`,
...(method === 'POST' && { 'Content-Type': 'application/json' }),
...options.extraHeaders
},
signal: controller.signal
}
if (method === 'POST' && body !== undefined) {
fetchOptions.body = JSON.stringify(body)
}
try {
const response = await fetch(`${this.baseURL}${path}`, fetchOptions)
if (!response.ok) {
const errorText = (await response.text().catch(() => '')).slice(0, 500)
throw new DashScopeApiError(`DashScope API error: ${response.status} - ${errorText}`, response.status)
}
return (await response.json()) as T
} catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
if (externallyAborted) throw createAbortError('DashScope API request aborted')
throw new Error(`DashScope API request timeout after ${timeout / 1000}s`)
}
throw error
} finally {
clearTimeout(timeoutId)
externalSignal?.removeEventListener('abort', onExternalAbort)
}
}
}
export function createDashScopeTransport(settings: DashScopeTransportSettings): DashScopeTransport {
return new DashScopeTransport(settings)
}View on GitHub (pinned to 726446b54c)
Solutions
- Read `error.statusCode`: 401/403 → fix the API key; 429 → back off and retry; 400 → inspect the body for the bad parameter; 5xx → retry with backoff.
- Confirm the API key resolves via `loadApiKey` (env `DASHSCOPE_API_KEY` or settings).
- For 429, reduce concurrency or space out requests.
Defensive patterns
Strategy: try-catch
Type guard
const isDashScopeApiError = (e: unknown): e is DashScopeApiError => e instanceof Error && e.name === 'DashScopeApiError'
Try / catch
try {
await transport.submit(input)
} catch (e) {
if (e instanceof DashScopeApiError) {
if (e.statusCode === 401 || e.statusCode === 403) /* fix API key */
else if (e.statusCode === 429) /* back off and retry */
else if (e.statusCode >= 500) /* retry with backoff */
else /* 4xx — inspect body, fix params */
}
throw e
} Prevention
- Branch on statusCode for tailored handling (auth vs quota vs validation)
- Retry 429/5xx with exponential backoff
- Log the first 500 chars of the body for diagnosis
When it happens
Trigger: 401/403 from a missing/invalid API key; 429 from rate/quota limits; 400 from a malformed request body; 5xx from a vendor outage. Thrown by both submit and poll requests.
Common situations: API key not set or revoked; exceeded DashScope QPS/concurrency; a parameter (size, n, seed) outside the model's accepted range; transient vendor 5xx during peak load.
Related errors
- responseBody || response.statusText
- Discord API error ${url}: HTTP ${response.status} - ${errorT
- Failed to get access token: HTTP ${response.status}
- QQ API request failed ${endpoint}: HTTP ${response.status} -
- Rerank response results must reference a valid document inde
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/5f46fc69bf20df18.
Report an issue: GitHub.