danny-avila/LibreChat · warning · Error

${response.status} ${response.statusText}

Error message

${response.status} ${response.statusText}

What it means

Thrown inside the batch SharePoint download path when an individual file's Graph content request returns non-2xx. This path is simpler than the single-file path: it calls `response.blob()` directly (no streaming reader) and constructs a `File`. The thrown message is just `${status} ${statusText}` (no `Download failed:` prefix), so it is harder to attribute to a specific item without surrounding context. The failure is collected into the batch's `failed` array rather than aborting the whole batch.

Source

Thrown at client/src/data-provider/Files/sharepoint.ts:141

      for (let i = 0; i < files.length; i += concurrencyLimit) {
        chunks.push(files.slice(i, i + concurrencyLimit));
      }

      for (const chunk of chunks) {
        const chunkPromises = chunk.map(async (file) => {
          try {
            const downloadUrl =
              file.downloadUrl ||
              `https://graph.microsoft.com/v1.0/drives/${file.driveId}/items/${file.itemId}/content`;

            const response = await fetch(downloadUrl, {
              headers: {
                Authorization: `Bearer ${accessToken}`,
              },
            });

            if (!response.ok) {
              throw new Error(`${response.status} ${response.statusText}`);
            }

            const blob = await response.blob();
            const contentType =
              response.headers.get('content-type') || getMimeTypeFromFileName(file.name);

            const downloadedFile = new File([blob], file.name, {
              type: contentType,
              lastModified: Date.now(),
            });

            completed++;
            onProgress?.({
              completed,
              total: files.length,
              currentFile: file.name,
              failed,
            });

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Inspect the batch result's `failed` array to see which file(s) failed and their status text.
  2. For token-expiry patterns (first files succeed, later ones 401), refresh the token midway through large batches or reduce batch size.
  3. For 404, instruct the user to re-pick the missing file; for 429/503, retry the failed subset with backoff.
  4. Prefer pre-issued `file.downloadUrl` values when present (they bypass per-item Graph auth) and refresh the picker if they expire.

Example fix

// before
if (!response.ok) {
  throw new Error(`${response.status} ${response.statusText}`);
}
// after — name the failing item and mark transient failures for retry
if (!response.ok) {
  const err = new Error(`Download failed for ${file.name} (${file.itemId}): ${response.status} ${response.statusText}`);
  err.file = file;
  err.status = response.status;
  err.retryable = response.status === 429 || response.status >= 500;
  throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Filter the batch to well-formed files before invoking the mutation
const valid = files.filter((f) => f.downloadUrl || (f.driveId && f.itemId));
if (!valid.length) throw new Error('No valid SharePoint files to download');

Type guard

function isSharePointFile(f: unknown): f is SharePointFile {
  return typeof f === 'object' && f !== null && typeof (f as any).name === 'string';
}

Try / catch

// Collect per-file failures rather than aborting the batch
try {
  const response = await fetch(downloadUrl, { headers });
  if (!response.ok) throw Object.assign(new Error(`${response.status}`), { file, status: response.status });
} catch (err) {
  failed.push(err.file?.name ?? 'unknown');
  continue;
}

Prevention

When it happens

Trigger: Same Graph failure modes as the single-file case: expired/under-scoped token (401/403), deleted/moved item (404), throttling (429/503). Because it runs per-file inside a batch, one bad item among many produces this error while the others succeed and increment `completed`.

Common situations: A multi-file selection where one file's permissions were revoked or it was moved after picking; token expiring mid-batch (large batch takes longer than token TTL); throttling on rapid sequential Graph calls; a stale `downloadUrl` on one item in the batch.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/6dc3e0a35b9c1491. Report an issue: GitHub.