iOfficeAI/AionUi · error · Error

File download failed (${response.status})

Error message

File download failed (${response.status})

What it means

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.

Source

Thrown at packages/desktop/src/renderer/utils/file/download.ts:47

  if (!dataUrl) {
    throw new Error('File data not found');
  }
  const ext = file_name.split('.').pop()?.toLowerCase() ?? '';
  const mimeType = BINARY_MIME_MAP[ext] ?? 'application/octet-stream';
  const blob = base64ToBlob(dataUrl, mimeType);
  triggerBlobDownload(blob, file_name);
}

/**
 * Download a file addressed by its renderer-safe file reference.
 *
 * Fetch the backend's raw byte stream rather than carrying the complete file as
 * base64 inside JSON. This is the same endpoint used by PDF previews and works
 * through both Electron's local backend and WebUI's same-origin reverse proxy.
 */
export async function downloadFileFromRef(file: ChatFileRef, file_name: string): Promise<void> {
  const response = await fetch(buildFileStreamUrl(file));
  if (!response.ok) throw new Error(`File download failed (${response.status})`);
  const blob = await response.blob();
  if (blob.size === 0) throw new Error('File data is empty');
  triggerBlobDownload(blob, file_name);
}

/**
 * Download in-memory text content as a file.
 */
export function downloadTextContent(content: string, file_name: string, mimeType: string): void {
  const blob = new Blob([content], { type: mimeType });
  triggerBlobDownload(blob, file_name);
}

View on GitHub (pinned to 711aa0550e)

Solutions

  1. Inspect the actual status code in the error to narrow cause: 404 = unknown ref, 500 = backend-side read failure, 502 = proxy/backend down.
  2. Verify the ChatFileRef (id/path/workspace) is current and the backend still has the file.
  3. Check that the backend service is running and reachable, and that the WebUI reverse proxy routes the stream endpoint correctly.
  4. Log buildFileStreamUrl(file) and curl it directly to see the raw response.

Example fix

// before
const response = await fetch(buildFileStreamUrl(file));
if (!response.ok) throw new Error(`File download failed (${response.status})`);

// after
const response = await fetch(buildFileStreamUrl(file));
if (!response.ok) {
  const detail = await response.text().catch(() => '');
  throw new Error(`File download failed (${response.status}) ${detail.slice(0, 200)}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(buildFileStreamUrl(file), { method: 'HEAD' });
if (!res.ok) { /* disable download / show reason */ }

Type guard

const isOkRef = (f: ChatFileRef): boolean => Boolean(f && f.path);

Try / catch

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 */ } }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28). Data as JSON: /api/errors/f38f5998584ad4d5. Report an issue: GitHub.