{"record":{"id":"65bda5853ec2928d","repo":"iOfficeAI/AionUi","slug":"file-data-not-found","errorCode":null,"errorMessage":"File data not found","messagePattern":"File data not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/desktop/src/renderer/utils/file/download.ts","lineNumber":30,"sourceCode":"function triggerBlobDownload(blob: Blob, file_name: string): void {\n  const url = URL.createObjectURL(blob);\n  const link = document.createElement('a');\n  link.href = url;\n  link.download = file_name;\n  document.body.appendChild(link);\n  link.click();\n  document.body.removeChild(link);\n  URL.revokeObjectURL(url);\n}\n\n/**\n * Download a file by reading its raw bytes from disk (works in both Electron and WebUI).\n * Uses getImageBase64 + in-memory atob decode to bypass CSP connect-src restrictions.\n */\nexport async function downloadFileFromPath(file_path: string, file_name: string, workspace?: string): Promise<void> {\n  const dataUrl = await ipcBridge.fs.getImageBase64.invoke({ path: file_path, workspace });\n  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();","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/iOfficeAI/AionUi/blob/711aa0550ee183ea495dc33e2c05c7943b70a60a/packages/desktop/src/renderer/utils/file/download.ts#L12-L48","documentation":"Thrown by downloadFileFromPath when the IPC call ipcBridge.fs.getImageBase64.invoke returns a falsy value (empty string or null) for the given file path. This means the main process read the file but produced no base64 data, or the file simply does not exist at the path provided. It is a renderer-side guard before attempting a blob download.","triggerScenarios":"Calling downloadFileFromPath with a file_path that has been deleted or moved (e.g. a chat artifact cleaned up from disk), passing a relative path when the IPC expects an absolute one, or supplying a workspace that does not contain the file so the main-process lookup resolves to nothing.","commonSituations":"Downloading generated images/files after the workspace cache or temp directory was cleared, stale chat history referencing removed artifacts, path mismatches between Windows and Unix separators, or the file existing in a different workspace than the one passed.","solutions":["Verify the file exists on disk at the exact path before calling download (fs stat via IPC or the main process).","Confirm you are passing the correct workspace argument matching where the file was created.","If the file was generated by a tool, re-run the tool or regenerate the artifact, then retry the download.","Add a user-facing message when getImageBase64 returns empty instead of a raw throw."],"exampleFix":"// before\nawait downloadFileFromPath(path, name);\n\n// after\nconst dataUrl = await ipcBridge.fs.getImageBase64.invoke({ path, workspace });\nif (!dataUrl) {\n  message.error(t('download.fileMissing', { defaultValue: 'File no longer exists' }));\n  return;\n}\nawait downloadFileFromPath(path, name, workspace);","handlingStrategy":"validation","validationCode":"const exists = await ipcBridge.fs.getFileStats?.invoke({ path: file_path, workspace });\nif (!exists) {\n  // show 'file missing' UI instead of calling downloadFileFromPath\n}","typeGuard":"const hasFileData = (d: string | null | undefined): d is string =>\n  typeof d === 'string' && d.length > 0;","tryCatchPattern":"try { await downloadFileFromPath(p, n, ws); } catch (e) { if ((e as Error).message === 'File data not found') { /* notify user, offer regenerate */ } else { throw e; } }","preventionTips":["Check file existence via IPC before offering the download button.","Pass the correct workspace for every download call.","Clean up UI references when underlying artifacts are deleted."],"tags":["ipc","file-not-found","download","electron"],"backgroundTag":"file-not-found","analyzedSha":"711aa0550ee183ea495dc33e2c05c7943b70a60a","analyzedAt":"2026-08-28T07:56:06.558Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}