Budibase/budibase · error · HTTPError
Failed to download SharePoint file (${response.status})
Error message
Failed to download SharePoint file (${response.status}) What it means
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.
Source
Thrown at packages/server/src/sdk/workspace/ai/knowledgeSources/sharepoint/connection.ts:899
itemId: string,
signal?: AbortSignal
) => {
const response = await fetch(
`${SHAREPOINT_API_BASE}/drives/${driveId}/items/${itemId}/content`,
{
signal,
headers: {
Authorization: bearerToken,
},
}
)
if (!response.ok) {
console.error("Failed to download SharePoint file", {
status: response.status,
driveId,
itemId,
})
throw new HTTPError(
response.status === 401 || response.status === 403
? "Access denied by Microsoft Graph. Ensure delegated SharePoint read permissions are granted."
: `Failed to download SharePoint file (${response.status})`,
400
)
}
return Buffer.from(await response.arrayBuffer())
}
View on GitHub (pinned to a81a902e9a)
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
Example fix
// before: immediate throw on non-ok
if (!response.ok) { throw new HTTPError(`Failed to download SharePoint file (${response.status})`, 400) }
// after: one retry on transient statuses
if (!response.ok && (response.status === 429 || response.status >= 500)) {
response = await fetch(url, init) // retry once after delay
}
if (!response.ok) { throw new HTTPError(`Failed to download SharePoint file (${response.status})`, 400) } Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: confirm the item still exists before downloading content
const meta = await fetch(`${graphUrl}/drives/${driveId}/items/${itemId}`, { headers: { Authorization: `Bearer ${token}` } })
if (meta.status === 404) return skipFile(itemId) // deleted/moved Try / catch
try {
await downloadSharePointFile(conn, driveId, itemId)
} catch (e) {
if (e instanceof HTTPError && e.message.includes("Failed to download SharePoint file")) {
log.warn({ driveId, itemId }, "sharepoint download failed, skipping file")
return null
}
throw e
} Prevention
- Throttle download concurrency to stay under Graph rate limits
- Re-check file existence between listing and download
- Exclude policy-blocked files before attempting download
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- OIDC Config contents invalid
- Koa context must be supplied to logout.
- Failed to fetch SharePoint drive item (${response.status})
- Error getting account by email ${email}
- Error getting account by tenantId ${tenantId}
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/71139f65d9b81307.
Report an issue: GitHub.