chatboxai/chatbox · error · ApiError
Status Code ${res.status}
Error message
Status Code ${res.status} What it means
Thrown by the standard (non-mobile) fetch path when res.ok is false: an ApiError is constructed with `Status Code ${res.status}` and, when readable, the response body as responseBody. This is the desktop/web equivalent of the mobile status-code error (228) and is the single failure exit for fetch-based provider calls, wrapped by retryRequest.
Source
Thrown at src/renderer/utils/request.ts:72
const { signal, retry = 3, useProxy = false, body, method } = options
let requestUrl = url
const headers = buildHeaders(options, url)
if (useProxy && !isLocalHost(url) && platform.type !== 'mobile') {
const version = await platform.getVersion()
headers.set('CHATBOX-VERSION', version || 'unknown')
requestUrl = 'https://cors-proxy.chatboxai.app/proxy-api/completions'
}
const makeRequest = async () => {
if (platform.type === 'mobile' && useProxy) {
return handleMobileRequest(requestUrl, method, headers, body, signal)
}
const res = await fetch(requestUrl, { method, headers, body, signal })
if (!res.ok) {
const err = await res.text().catch(() => null)
throw new ApiError(`Status Code ${res.status}`, err ?? undefined)
}
return res
}
return retryRequest(makeRequest, retry, requestUrl)
}
export const apiRequest = {
async post(
url: string,
headers: Record<string, string>,
body: RequestInit['body'],
options?: Partial<RequestOptions>
) {
return doRequest(url, { ...options, method: 'POST', headers, body })
},
async get(url: string, headers: Record<string, string>, options?: Partial<RequestOptions>) {View on GitHub (pinned to 81571269ad)
Solutions
- Read ApiError.responseBody — most providers put a JSON error object there with a specific code/message that points at the fix.
- Match on statusCode: 401/403 → rotate/fix the API key; 429 → reduce request rate / implement backoff; 5xx → retry then check provider status page.
- For CORS/TLS errors, route the request through the cors-proxy (set useProxy) or fix the server's CORS headers.
- Verify the request URL and CHATBOX-VERSION header — a wrong apiPath or stale version can yield 404/400.
Example fix
// before
const res = await fetch(requestUrl, { method, headers, body, signal })
if (!res.ok) {
const err = await res.text().catch(() => null)
throw new ApiError(`Status Code ${res.status}`, err ?? undefined)
}
// after — parse the body so callers get structured detail
const res = await fetch(requestUrl, { method, headers, body, signal })
if (!res.ok) {
const err = await res.text().catch(() => null)
throw new ApiError(`Status Code ${res.status}`, err ?? undefined, res.status)
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight header/url sanity check before fetch.
function assertRequestShape(url: string, headers: Record<string,string>): void {
new URL(url) // throws on malformed
if (!headers['Authorization'] && !headers['CHATBOX-VERSION']) {
console.warn('Request may lack auth/version headers')
}
} Type guard
function isApiError(e: unknown): e is ApiError {
return e instanceof ApiError
} Try / catch
try {
return await apiRequest.post(url, headers, body)
} catch (e) {
if (e instanceof ApiError) {
if (e.statusCode === 429) return retryWithBackoff(() => apiRequest.post(url, headers, body))
if (e.statusCode === 401) rotateApiKey()
if (e.statusCode && e.statusCode >= 500) return retryWithBackoff(() => apiRequest.post(url, headers, body))
}
throw e
} Prevention
- Parse ApiError.responseBody as JSON when possible to extract provider-specific error codes.
- Set sensible retry counts on retryRequest so transient 5xx/429 are retried automatically.
- Validate apiHost and CHATBOX-VERSION before requests — wrong values yield 404/400.
When it happens
Trigger: fetch resolves with a non-OK status (res.ok === false, i.e. status outside 200–299). The body is read via res.text() (null on read failure). The error propagates through retryRequest, which may re-invoke makeRequest up to the retry count before this error reaches the caller.
Common situations: Provider returned 401 (bad key), 429 (rate limit), 5xx (server error); CORS error surfaced as a network failure (these usually reject fetch, but opaque responses can land here); self-signed cert / TLS issue; provider deprecated an endpoint (404); upstream gateway timeout (504).
Related errors
- Knowledge base name cannot be empty
- No response body
- Status Code ${response.status}
- Report failed with status ${response.status}
- Knowledge base name is required
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/b83ab4873958b2ba.
Report an issue: GitHub.