{"record":{"id":"19fe5bc781228569","repo":"CherryHQ/cherry-studio","slug":"responsebody-response-statustext-19fe5b","errorCode":null,"errorMessage":"responseBody || response.statusText","messagePattern":"responseBody \\|\\| response\\.statusText","errorType":"exception","errorClass":"APICallError","httpStatus":null,"severity":"error","filePath":"src/main/ai/provider/custom/silicon/SiliconImageModel.ts","lineNumber":116,"sourceCode":"    const url = this.config.url({ path: '/images/generations', modelId: this.modelId })\n    const fetchFn = this.config.fetch ?? globalThis.fetch\n    const response = await fetchFn(url, {\n      method: 'POST',\n      headers: removeUndefinedEntries(\n        combineHeaders(this.config.headers(), headers, { 'Content-Type': 'application/json' })\n      ),\n      body: JSON.stringify(body),\n      signal: abortSignal\n    })\n\n    const responseHeaders: Record<string, string> = {}\n    response.headers.forEach((value, key) => {\n      responseHeaders[key] = value\n    })\n    const responseBody = await response.text()\n\n    if (!response.ok) {\n      throw new APICallError({\n        message: responseBody || response.statusText,\n        url,\n        requestBodyValues: body,\n        statusCode: response.status,\n        responseHeaders,\n        responseBody\n      })\n    }\n\n    let parsed: ImageResponseBody\n    try {\n      parsed = JSON.parse(responseBody) as ImageResponseBody\n    } catch (cause) {\n      throw new APICallError({\n        message: 'Invalid JSON response from SiliconFlow',\n        cause,\n        url,\n        requestBodyValues: body,","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/provider/custom/silicon/SiliconImageModel.ts#L98-L134","documentation":"APICallError is the AI SDK's standard error for a failed provider HTTP call. SiliconImageModel.doGenerate throws it when SiliconFlow's /images/generations returns non-ok. The message is the raw response body (or response.statusText if the body is empty), and the error carries url, statusCode, responseHeaders, requestBodyValues, and responseBody for diagnostics.","triggerScenarios":"POST /images/generations to siliconflow.cn returns 4xx/5xx. Concrete causes: missing/invalid API key (401), insufficient balance (402/429), unknown model id (400/404), unsupported image_size value (422), NSFW rejection, malformed prompt, or 5xx during outage.","commonSituations":"First run with unset apiKey, balance exhausted mid-batch, model id drift after SiliconFlow renames, invalid image_size (must be a supported WxH), aspectRatio passed but unsupported, or transient 5xx.","solutions":["Read error.statusCode and error.message: 401 → fix apiKey; 402/429 → top up balance / back off; 400/422 → inspect the body for the offending field (often image_size or model id); 5xx → retry.","Confirm the model id is valid for SiliconFlow image generation (Kolors, Qwen-Image, FLUX, Z-Image, etc.).","Validate image_size against SiliconFlow's supported list before submit.","For transient 5xx, retry with exponential backoff at the call site."],"exampleFix":"// before\nthrow new APICallError({ message: responseBody || response.statusText, statusCode: response.status, ... })\n// after — also surface the model id and a hint\nthrow new APICallError({\n  message: `SiliconFlow image generation for '${this.modelId}' failed (${response.status}): ${responseBody || response.statusText}`,\n  statusCode: response.status, url, requestBodyValues: body, responseHeaders, responseBody\n})","handlingStrategy":"try-catch","validationCode":"if (!settings.apiKey) throw new Error('SiliconFlow apiKey is required')\nif (size && !SILICON_SUPPORTED_SIZES.includes(size)) {\n  throw new Error(`Unsupported image_size '${size}' for SiliconFlow`)\n}","typeGuard":"import { APICallError } from '@ai-sdk/provider'\nexport function isSiliconApiError(e: unknown): e is APICallError {\n  return e instanceof APICallError && typeof e.statusCode === 'number' && /silicon/i.test(e.url ?? '')\n}","tryCatchPattern":"try {\n  await imageModel.doGenerate(opts)\n} catch (e) {\n  if (e instanceof APICallError && (e.statusCode ?? 0) >= 500) {\n    await backoffRetry(() => imageModel.doGenerate(opts))\n  }\n  throw e\n}","preventionTips":["Validate apiKey and image_size against SiliconFlow's supported list before submit.","Use APICallError.statusCode to separate terminal (4xx) from transient (5xx).","Inspect error.message — it usually names the offending field."],"tags":["siliconflow","api","http","ai-sdk","image-generation"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}