chatboxai/chatbox · error · Error

Report failed with status ${response.status}

Error message

Report failed with status ${response.status}

What it means

Thrown by reportNativeContent (src/shared/services/native-report.ts:27) when the POST to {apiOrigin}/api/report_content returns a non-2xx status. The function posts { id, type, details } with an injectable fetchFn and origin (defaulting to the Chatbox origin) and has no body parsing or retry; any HTTP failure surfaces as a bare status code in the message.

Source

Thrown at src/shared/services/native-report.ts:27

export interface ReportNativeContentOptions {
  id: string
  type: string
  details: string
  apiOrigin?: string
  fetchFn?: typeof fetch
  headers?: Record<string, string>
}

export async function reportNativeContent(options: ReportNativeContentOptions): Promise<void> {
  const fetchFn = options.fetchFn ?? fetch
  const origin = (options.apiOrigin?.trim() || CHATBOX_DEFAULT_ORIGIN).replace(/\/+$/, '')
  const response = await fetchFn(`${origin}/api/report_content`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', ...options.headers },
    body: JSON.stringify({ id: options.id, type: options.type, details: options.details }),
  })
  if (!response.ok) {
    throw new Error(`Report failed with status ${response.status}`)
  }
}

View on GitHub (pinned to 81571269ad)

Solutions

  1. Wrap the call in try/catch and surface a user-facing 'report failed, try again' message; reporting is best-effort and should not block the UI.
  2. Confirm options.apiOrigin (if overridden) is correct; omit it to use the Chatbox default origin.
  3. Validate that options.id, options.type, and options.details are non-empty and of the expected shape before sending.
  4. On 429, back off and let the user retry rather than spamming the endpoint.
  5. Inspect the real status by reproducing the POST with curl against the target origin.

Example fix

// before
await reportNativeContent({ id, type, details })

// after
try {
  await reportNativeContent({ id, type, details })
} catch (e) {
  toastActions.add((e as Error).message)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Reject incomplete report payloads before the network call
function assertReportInput(o: ReportNativeContentOptions) {
  if (!o.id) throw new Error('report id is required')
  if (!o.type) throw new Error('report type is required')
}

Try / catch

// Reporting is best-effort; never block the UI on it
try {
  await reportNativeContent({ id, type, details })
} catch (e) {
  toastActions.add((e as Error).message || t('Report failed'))
}

Prevention

When it happens

Trigger: fetchFn POST to `${origin}/api/report_content` returns response.ok === false. Common codes: 400 (bad/missing id, type, or details), 401/403 (auth required for the resource being reported), 404 (wrong apiOrigin), 429 (rate limited), 5xx (server). Also fires when apiOrigin is misconfigured to a host that returns a non-2xx for the path.

Common situations: User clicks 'Report' on content whose id/type the server no longer recognizes; apiOrigin override points at the wrong environment; report endpoint temporarily down; client hitting rate limits after repeated reports; a missing/blank options.id or options.type rejected by server-side validation.

Related errors


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