CherryHQ/cherry-studio · error · APICallError
Invalid JSON response from SiliconFlow
Error message
Invalid JSON response from SiliconFlow
What it means
APICallError thrown when SiliconImageModel.doGenerate receives an ok HTTP status but the body is not valid JSON (JSON.parse throws). The original parse error is attached as `cause`. This guards against the SDK handing a parse error to image-decoding logic downstream; the response body is preserved on the error for inspection.
Source
Thrown at src/main/ai/provider/custom/silicon/SiliconImageModel.ts:130
})
const responseBody = await response.text()
if (!response.ok) {
throw new APICallError({
message: responseBody || response.statusText,
url,
requestBodyValues: body,
statusCode: response.status,
responseHeaders,
responseBody
})
}
let parsed: ImageResponseBody
try {
parsed = JSON.parse(responseBody) as ImageResponseBody
} catch (cause) {
throw new APICallError({
message: 'Invalid JSON response from SiliconFlow',
cause,
url,
requestBodyValues: body,
statusCode: response.status,
responseHeaders,
responseBody
})
}
const items = parsed.images ?? parsed.data ?? []
const images: string[] = items.flatMap((item) => {
if (typeof item.b64_json === 'string') return [item.b64_json]
if (typeof item.url === 'string') return [item.url]
return []
})
return {View on GitHub (pinned to 726446b54c)
Solutions
- Inspect error.responseBody — if it is HTML or empty, the request never reached the real SiliconFlow API; treat as transient and retry.
- Verify the configured baseURL resolves to the real siliconflow.cn API and not a captive portal/proxy page.
- Check network egress for transparent proxies rewriting the response.
- If intermittent, add a retry with backoff; if persistent, report a vendor/network issue.
Example fix
// before
parsed = JSON.parse(responseBody) as ImageResponseBody
// after — guard and surface what we got
let parsed: ImageResponseBody
try { parsed = JSON.parse(responseBody) as ImageResponseBody }
catch (cause) { throw new APICallError({ message: `SiliconFlow returned non-JSON body (len=${responseBody.length}): ${responseBody.slice(0,200)}`, cause, ... }) } Defensive patterns
Strategy: retry
Validate before calling
// Pre-check reachability if a captive portal / proxy is suspected
const probe = await fetch(baseURL, { method: 'HEAD' })
const ct = probe.headers.get('content-type') ?? ''
if (ct.includes('text/html')) throw new Error('SiliconFlow endpoint returned HTML; check baseURL/proxy') Type guard
export function isSiliconNonJsonError(e: unknown): boolean {
return e instanceof APICallError && /Invalid JSON response from SiliconFlow/.test(e.message)
} Try / catch
try {
await imageModel.doGenerate(opts)
} catch (e) {
if (isSiliconNonJsonError(e)) {
// CDN/gateway returned HTML; retry once
await backoffRetry(() => imageModel.doGenerate(opts), { maxAttempts: 1 })
}
throw e
} Prevention
- Verify baseURL resolves to the real siliconflow.cn API, not a captive portal.
- Treat non-JSON 2xx as transient and retry once.
- Inspect error.responseBody — HTML or empty signals a network/proxy issue, not a vendor API error.
When it happens
Trigger: SiliconFlow returns 2xx but the body is HTML (a CDN/proxy error page), empty, truncated, or otherwise non-JSON. Concrete causes: gateway/CDN serving an HTML error page with 200, partial response due to connection drop, vendor maintenance returning an HTML banner, or a reverse-proxy injecting content.
Common situations: Vendor outage behind a CDN returning a friendly HTML error page, corporate proxy rewriting responses, mid-stream disconnect leaving truncated body, or a regional gateway returning an HTML interstitial.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Rerank response results must contain numeric index and relev
- ModelScope API error: ${response.status} - ${errorText}
- ModelScope API request timeout after ${timeout / 1000}s
- errorData.error?.message || 'Image generation failed'
- PPIO API error: ${response.status} - ${errorText}
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/def231d60264c9ef.
Report an issue: GitHub.