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

  1. Read ApiError.responseBody — most providers put a JSON error object there with a specific code/message that points at the fix.
  2. Match on statusCode: 401/403 → rotate/fix the API key; 429 → reduce request rate / implement backoff; 5xx → retry then check provider status page.
  3. For CORS/TLS errors, route the request through the cors-proxy (set useProxy) or fix the server's CORS headers.
  4. 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

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


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/b83ab4873958b2ba. Report an issue: GitHub.