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

  1. 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.
  2. Confirm the API key resolves via `loadApiKey` (env `DASHSCOPE_API_KEY` or settings).
  3. 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

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


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/5f46fc69bf20df18. Report an issue: GitHub.