{"record":{"id":"76682bfb25c5748c","repo":"BloopAI/vibe-kanban","slug":"export-failed-response-status","errorCode":null,"errorMessage":"Export failed (${response.status})","messagePattern":"Export failed \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/web-core/src/features/export/ui/ExportDownload.tsx","lineNumber":49,"sourceCode":"  const [error, setError] = useState<string | null>(null);\n  const [downloadUrl, setDownloadUrl] = useState<string | null>(null);\n  const [filename, setFilename] = useState('vibe-kanban-export.zip');\n  const hasStartedRef = useRef(false);\n\n  const startExport = useCallback(async () => {\n    setIsExporting(true);\n    setError(null);\n    setDownloadUrl(null);\n\n    try {\n      const response = await exportFn({\n        organization_id: orgId,\n        project_ids: projectIds,\n        include_attachments: includeAttachments,\n      });\n\n      if (!response.ok) {\n        throw new Error(`Export failed (${response.status})`);\n      }\n\n      let downloadFilename = 'vibe-kanban-export.zip';\n      const disposition = response.headers.get('content-disposition');\n      if (disposition) {\n        const match = disposition.match(/filename=\"?([^\"]+)\"?/);\n        if (match) {\n          downloadFilename = match[1];\n        }\n      }\n      setFilename(downloadFilename);\n\n      const blob = await response.blob();\n      const url = URL.createObjectURL(blob);\n      setDownloadUrl(url);\n\n      const a = document.createElement('a');\n      a.href = url;","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/features/export/ui/ExportDownload.tsx#L31-L67","documentation":"ExportDownload POSTs an export request and streams the resulting zip. If the export endpoint responds with a non-ok status it throws `Export failed (${response.status})`, embedding the HTTP status code. Filename is then parsed from content-disposition with a default of 'vibe-kanban-export.zip'.","triggerScenarios":"Export request returns non-ok: too many/too large project_ids (payload limit), server timeout building a huge export, 401/403 on the org scope, or export service unavailable.","commonSituations":"Exporting an entire large organization times out (504); include_attachments balloons payload size; session expires mid-export (401); misconfigured orgId from stale route params.","solutions":["Read the status in the message: 401 → re-authenticate; 403 → check org permissions; 500/504 → retry with fewer projects or attachments off","Reduce export scope (fewer project_ids, includeAttachments=false) and retry","Verify orgId/projectIds are current values, not stale route state","Implement a polling/async export flow for very large exports instead of a single request"],"exampleFix":"// before\nawait runExport({ orgId, projectIds, includeAttachments: true });\n// after\ntry {\n  await runExport({ orgId, projectIds, includeAttachments: true });\n} catch (e) {\n  if (String(e).includes('504')) await runExport({ orgId, projectIds: projectIds.slice(0, 10), includeAttachments: false });\n  else notify.error(String(e));\n}","handlingStrategy":"try-catch","validationCode":"if (!orgId) throw new Error('organization required');\nif (!projectIds.length || projectIds.length > 100) throw new Error('select 1–100 projects to export');","typeGuard":"function isExportOptions(o: unknown): o is ExportOptions { return typeof o === 'object' && o !== null && typeof (o as any).orgId === 'string' && Array.isArray((o as any).projectIds); }","tryCatchPattern":"try {\n  await runExport({ orgId, projectIds, includeAttachments });\n} catch (e) {\n  const m = /Export failed \\((\\d+)\\)/.exec(String(e));\n  const status = m ? Number(m[1]) : 0;\n  if (status === 401) reauth(); else notify.error(String(e));\n}","preventionTips":["Cap export scope (project count, attachments) to keep the request under server limits","Re-validate auth before initiating long exports","Parse the status code out of the thrown message to branch recovery logic","Offer async/polling export for large organizations"],"tags":["export","http","download"],"backgroundTag":"http-request-failed","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}