{"record":{"id":"1c963ed95b06ba76","repo":"paperclipai/paperclip","slug":"body-error-export-failed-res-status","errorCode":null,"errorMessage":"${body?.error ?? `Export failed: ${res.status}`}","messagePattern":"\\$\\{body\\?\\.error \\?\\? `Export failed: \\$\\{res\\.status\\}`\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/api/audit.ts","lineNumber":117,"sourceCode":"   * Fetch the filtered feed as a CSV blob. The server logs an `audit.exported`\n   * activity row for the export itself (training-data export precedent).\n   */\n  exportAgentActionsCsv: async (\n    companyId: string,\n    filters: Omit<AuditActionFilters, \"cursor\" | \"limit\"> = {},\n  ): Promise<Blob> => {\n    const search = buildAuditQuery(filters);\n    const qs = search.toString();\n    const res = await fetch(\n      `/api/companies/${companyId}/audit/agent-actions.csv${qs ? `?${qs}` : \"\"}`,\n      { credentials: \"include\", headers: { Accept: \"text/csv\" } },\n    );\n    if (!res.ok) {\n      const body = await res.json().catch(() => null);\n      const recovery = tenantSessionRecovery.recoverIfNeeded(res.status, body);\n      if (recovery) return recovery;\n      const message = (body as { error?: string } | null)?.error ?? `Export failed: ${res.status}`;\n      throw new Error(message);\n    }\n    return res.blob();\n  },\n};\n","sourceCodeStart":99,"sourceCodeEnd":122,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/api/audit.ts#L99-L122","documentation":"The UI audit export API client performs tenant-session recovery on failed responses; if recovery does not apply, it throws an Error whose message is the server-provided body.error string, or a synthesized 'Export failed: <status>' when the body has no error field.","triggerScenarios":"The audit export fetch resolves but res.ok is false (4xx/5xx from /api audit export endpoint), and tenantSessionRecovery.recoverIfNeeded returns falsy.","commonSituations":"Session lacks permission for the audit scope (403), export range too large (500/413), tenant session expired on a multi-tenant deployment not handled by recovery, transient server error during export.","solutions":["Check the thrown message/body.error for the server's specific cause and fix that (permissions, date range size)","Re-authenticate: log in again or refresh the tenant session if status was 401","Retry with a smaller date range / narrower filters if the export is timing out or too large"],"exampleFix":"// before\nawait exportAuditLog({ range: 'all' });\n// after: narrow the export window\nawait exportAuditLog({ from: lastWeek, to: today });","handlingStrategy":"try-catch","validationCode":"if (!res.ok) { const body = await res.json().catch(() => null); console.error('Export failed', res.status, body?.error); }","typeGuard":null,"tryCatchPattern":"try { const blob = await auditApi.export(params); } catch (e) { if (e.message.includes('Export failed')) { showToast(`Audit export unavailable: ${e.message}`); } else throw e; }","preventionTips":["Check authentication/tenant session validity before large exports","Keep export ranges bounded to avoid server-side failures","Parse body.error server responses and surface them distinctly from network failures"],"tags":["http","export","ui"],"backgroundTag":"http-error-response","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}