{"record":{"id":"f38f5998584ad4d5","repo":"iOfficeAI/AionUi","slug":"file-download-failed-response-status","errorCode":null,"errorMessage":"File download failed (${response.status})","messagePattern":"File download failed \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/desktop/src/renderer/utils/file/download.ts","lineNumber":47,"sourceCode":"  if (!dataUrl) {\n    throw new Error('File data not found');\n  }\n  const ext = file_name.split('.').pop()?.toLowerCase() ?? '';\n  const mimeType = BINARY_MIME_MAP[ext] ?? 'application/octet-stream';\n  const blob = base64ToBlob(dataUrl, mimeType);\n  triggerBlobDownload(blob, file_name);\n}\n\n/**\n * Download a file addressed by its renderer-safe file reference.\n *\n * Fetch the backend's raw byte stream rather than carrying the complete file as\n * base64 inside JSON. This is the same endpoint used by PDF previews and works\n * through both Electron's local backend and WebUI's same-origin reverse proxy.\n */\nexport async function downloadFileFromRef(file: ChatFileRef, file_name: string): Promise<void> {\n  const response = await fetch(buildFileStreamUrl(file));\n  if (!response.ok) throw new Error(`File download failed (${response.status})`);\n  const blob = await response.blob();\n  if (blob.size === 0) throw new Error('File data is empty');\n  triggerBlobDownload(blob, file_name);\n}\n\n/**\n * Download in-memory text content as a file.\n */\nexport function downloadTextContent(content: string, file_name: string, mimeType: string): void {\n  const blob = new Blob([content], { type: mimeType });\n  triggerBlobDownload(blob, file_name);\n}\n","sourceCodeStart":29,"sourceCodeEnd":60,"githubUrl":"https://github.com/iOfficeAI/AionUi/blob/711aa0550ee183ea495dc33e2c05c7943b70a60a/packages/desktop/src/renderer/utils/file/download.ts#L29-L60","documentation":"Thrown by downloadFileFromRef when the HTTP fetch to the backend's file-stream endpoint returns a non-OK status. The endpoint is the same one used for PDF previews and streams raw bytes from the local backend (Electron) or the WebUI same-origin reverse proxy. Any 4xx/5xx (typically 404 or 500) triggers this error.","triggerScenarios":"Fetching buildFileStreamUrl(file) where file's reference id/path is unknown to the backend (404), the backend process is down or restarted (502/connection issues surface as non-ok), or the WebUI reverse proxy cannot reach the backend service.","commonSituations":"Downloading a file from an old conversation after backend data was reset, reverse proxy misconfiguration in WebUI deployments, expired auth/session on the stream endpoint, or a backend version that changed the stream URL shape.","solutions":["Inspect the actual status code in the error to narrow cause: 404 = unknown ref, 500 = backend-side read failure, 502 = proxy/backend down.","Verify the ChatFileRef (id/path/workspace) is current and the backend still has the file.","Check that the backend service is running and reachable, and that the WebUI reverse proxy routes the stream endpoint correctly.","Log buildFileStreamUrl(file) and curl it directly to see the raw response."],"exampleFix":"// before\nconst response = await fetch(buildFileStreamUrl(file));\nif (!response.ok) throw new Error(`File download failed (${response.status})`);\n\n// after\nconst response = await fetch(buildFileStreamUrl(file));\nif (!response.ok) {\n  const detail = await response.text().catch(() => '');\n  throw new Error(`File download failed (${response.status}) ${detail.slice(0, 200)}`);\n}","handlingStrategy":"try-catch","validationCode":"const res = await fetch(buildFileStreamUrl(file), { method: 'HEAD' });\nif (!res.ok) { /* disable download / show reason */ }","typeGuard":"const isOkRef = (f: ChatFileRef): boolean => Boolean(f && f.path);","tryCatchPattern":"try { await downloadFileFromRef(file, name); } catch (e) { const m = (e as Error).message; if (m.startsWith('File download failed')) { const status = Number(m.match(/\\((\\d+)\\)/)?.[1]); /* handle 404 vs 5xx */ } }","preventionTips":["Health-check the backend before enabling downloads.","Include response body detail in thrown errors for diagnosis.","Validate ChatFileRef fields before invoking."],"tags":["http","download","fetch","backend"],"backgroundTag":"http-request-failed","analyzedSha":"711aa0550ee183ea495dc33e2c05c7943b70a60a","analyzedAt":"2026-08-28T07:56:06.558Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}