chatboxai/chatbox · error · ApiError
Status Code ${response.status}
Error message
Status Code ${response.status} What it means
Thrown by the mobile HTTP shim (CapacitorHttp) after a request completes: when response.status is 0 (no response / CORS / native failure), < 200, or >= 400, an ApiError is constructed with the raw body as its message payload and the numeric status. It is the single failure exit for all mobile network calls routed through this shim.
Source
Thrown at src/renderer/utils/mobile-request.ts:91
},
})
} catch (err) {
console.warn('Native streaming unavailable, falling back', err)
}
}
const response = await CapacitorHttp.request({
url,
method,
headers: headerObj,
data: body,
responseType: 'text',
})
const rawData = typeof response.data === 'string' ? response.data : JSON.stringify(response.data)
// Treat status 0 or < 200 as errors, in addition to >= 400
if (response.status === 0 || response.status < 200 || response.status >= 400) {
throw new ApiError(`Status Code ${response.status}`, rawData, response.status)
}
const responseData = rawData
if (isStreaming) {
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(responseData))
controller.close()
},
})
return new Response(stream, {
status: response.status,
headers: { ...response.headers, 'Content-Type': 'text/event-stream' },
})
}
return new Response(responseData, {
status: response.status,View on GitHub (pinned to 81571269ad)
Solutions
- Read the ApiError.statusCode — 401/403 → fix API key/headers; 429 → back off and retry; 5xx → provider outage, retry with exponential backoff; 0 → check device connectivity and ATS/CORS config.
- Inspect ApiError.responseBody for the server's actual error message — HTML bodies typically indicate a gateway/proxy error, not an API error.
- For self-hosted providers, ensure the endpoint sends permissive CORS headers and HTTPS (ATS blocks plain HTTP on iOS).
- If status is consistently 0 on Android, verify the network_security_config / cleartext policy permits the host.
Example fix
// before
if (response.status === 0 || response.status < 200 || response.status >= 400) {
throw new ApiError(`Status Code ${response.status}`, rawData, response.status)
}
// after — distinguish no-response from HTTP error for clearer UX
if (response.status === 0) {
throw new ApiError('No response (network/CORS/ATS failure)', rawData, 0)
}
if (response.status < 200 || response.status >= 400) {
throw new ApiError(`Status Code ${response.status}`, rawData, response.status)
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-validate the URL scheme and connectivity before issuing the CapacitorHttp call.
function isMobileRequestLikelyToSucceed(url: string): boolean {
try {
const u = new URL(url)
return u.protocol === 'https:' || u.protocol === 'http:'
} catch { return false }
} Type guard
function isApiErrorWithStatus(e: unknown): e is ApiError & { statusCode: number } {
return e instanceof ApiError && typeof (e as any).statusCode === 'number'
} Try / catch
try {
return await mobileRequest(url, opts)
} catch (e) {
if (e instanceof ApiError && typeof e.statusCode === 'number') {
if (e.statusCode === 0) showUser('Network unavailable. Check your connection.')
else if (e.statusCode >= 500) return retryWithBackoff(() => mobileRequest(url, opts))
else if (e.statusCode === 401) rotateApiKey()
}
throw e
} Prevention
- Whitelist hosts in network_security_config (Android) and ATS (iOS) before shipping.
- Distinguish status 0 (network/CORS) from HTTP errors in the error UI so users get the right remediation.
- Inspect ApiError.responseBody before assuming JSON — gateway errors are often HTML.
When it happens
Trigger: CapacitorHttp.request resolves with a non-2xx status: server returns 4xx/5xx; status 0 from a DNS/CORS/native-network failure; rawData is the stringified body (HTML error page, JSON error, or empty). The thrown ApiError carries rawData as responseBody and response.status as statusCode.
Common situations: Provider endpoint down (502/503/504); invalid API key (401); rate limit (429); mobile platform blocking the URL via App Transport Security; CORS misconfiguration on a self-hosted endpoint; offline/no network giving status 0; server returning HTML instead of JSON.
Related errors
- Status Code ${res.status}
- Report failed with status ${response.status}
- Knowledge base name cannot be empty
- Token exchange failed: ${error}
- Token refresh failed: ${error}
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/1e8bd82e35ccaf87.
Report an issue: GitHub.