{"record":{"id":"71139f65d9b81307","repo":"Budibase/budibase","slug":"failed-to-download-sharepoint-file-response-sta","errorCode":null,"errorMessage":"Failed to download SharePoint file (${response.status})","messagePattern":"Failed to download SharePoint file \\((.+?)\\)","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/ai/knowledgeSources/sharepoint/connection.ts","lineNumber":899,"sourceCode":"  itemId: string,\n  signal?: AbortSignal\n) => {\n  const response = await fetch(\n    `${SHAREPOINT_API_BASE}/drives/${driveId}/items/${itemId}/content`,\n    {\n      signal,\n      headers: {\n        Authorization: bearerToken,\n      },\n    }\n  )\n  if (!response.ok) {\n    console.error(\"Failed to download SharePoint file\", {\n      status: response.status,\n      driveId,\n      itemId,\n    })\n    throw new HTTPError(\n      response.status === 401 || response.status === 403\n        ? \"Access denied by Microsoft Graph. Ensure delegated SharePoint read permissions are granted.\"\n        : `Failed to download SharePoint file (${response.status})`,\n      400\n    )\n  }\n  return Buffer.from(await response.arrayBuffer())\n}\n","sourceCodeStart":881,"sourceCodeEnd":908,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/ai/knowledgeSources/sharepoint/connection.ts#L881-L908","documentation":"Thrown when the Microsoft Graph download of a SharePoint file's content returns a non-ok response that is not 401/403. The failing status is logged (with driveId and itemId) before throwing an HTTPError with status 400. It distinguishes content-download failures from metadata-fetch failures.","triggerScenarios":"The Graph content endpoint (e.g. /drives/{driveId}/items/{itemId}/content) responds 404 (file deleted), 429 (throttled), 302-follow failures, or 5xx while downloading a file for AI knowledge ingestion. 401/403 produce the access-denied message instead.","commonSituations":"Large-file downloads throttled by Graph during bulk knowledge-source syncs; the file was moved/deleted between listing and download; OneDrive personal files blocked from download by policy.","solutions":["Check the logged status for the specific driveId/itemId; retry with backoff on 429/5xx","Confirm the file still exists at the itemId (a 404 means it was deleted/moved — re-sync the drive listing)","Reduce sync concurrency to avoid Graph throttling","Verify download policy on the SharePoint site allows content export"],"exampleFix":"// before: immediate throw on non-ok\nif (!response.ok) { throw new HTTPError(`Failed to download SharePoint file (${response.status})`, 400) }\n// after: one retry on transient statuses\nif (!response.ok && (response.status === 429 || response.status >= 500)) {\n  response = await fetch(url, init) // retry once after delay\n}\nif (!response.ok) { throw new HTTPError(`Failed to download SharePoint file (${response.status})`, 400) }","handlingStrategy":"retry","validationCode":"// pre-flight: confirm the item still exists before downloading content\nconst meta = await fetch(`${graphUrl}/drives/${driveId}/items/${itemId}`, { headers: { Authorization: `Bearer ${token}` } })\nif (meta.status === 404) return skipFile(itemId) // deleted/moved","typeGuard":null,"tryCatchPattern":"try {\n  await downloadSharePointFile(conn, driveId, itemId)\n} catch (e) {\n  if (e instanceof HTTPError && e.message.includes(\"Failed to download SharePoint file\")) {\n    log.warn({ driveId, itemId }, \"sharepoint download failed, skipping file\")\n    return null\n  }\n  throw e\n}","preventionTips":["Throttle download concurrency to stay under Graph rate limits","Re-check file existence between listing and download","Exclude policy-blocked files before attempting download"],"tags":["sharepoint","microsoft-graph","http","file-download"],"backgroundTag":"upstream-http-error","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}