{"record":{"id":"207ddd7efe9a73ed","repo":"Budibase/budibase","slug":"failed-to-fetch-sharepoint-drive-item-response","errorCode":null,"errorMessage":"Failed to fetch SharePoint drive item (${response.status})","messagePattern":"Failed to fetch SharePoint drive item \\((.+?)\\)","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/ai/knowledgeSources/sharepoint/connection.ts","lineNumber":811,"sourceCode":"        `${SHAREPOINT_API_BASE}/drives/${encodeURIComponent(\n          driveId\n        )}/items/${encodeURIComponent(\n          itemId\n        )}?$select=id,name,eTag,lastModifiedDateTime,size,file,folder,parentReference`,\n        {\n          signal,\n          headers: {\n            Authorization: bearerToken,\n          },\n        }\n      ),\n    signal\n  )\n  if (response.status === 404) {\n    return undefined\n  }\n  if (!response.ok) {\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 fetch SharePoint drive item (${response.status})`,\n      400\n    )\n  }\n  return (await response.json()) as SharePointDriveItem\n}\n\nexport const collectSharePointFilesRecursive = async (\n  bearerToken: string,\n  driveId: string,\n  folderId?: string,\n  parentPath = \"\",\n  signal?: AbortSignal\n): Promise<SharePointFileRef[]> => {\n  const items = await listSharePointDriveItems(\n    bearerToken,","sourceCodeStart":793,"sourceCodeEnd":829,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/ai/knowledgeSources/sharepoint/connection.ts#L793-L829","documentation":"Thrown when a Microsoft Graph API call to fetch a SharePoint drive item returns a non-ok response that is not 401/403/404. The status code is embedded in the message and it is wrapped as an HTTPError with status 400. It exists to surface unexpected Graph failures (rate limits, 5xx, malformed requests) with a clear SharePoint-specific message.","triggerScenarios":"Calling the SharePoint knowledge-source connection which issues a Graph GET for a drive item and receives e.g. 429 (throttled), 500/503 (Graph outage), or 400 (bad driveId/itemId format). 404 returns undefined and 401/403 produce the access-denied message instead.","commonSituations":"Graph service degradation or throttling during large bulk syncs; a stale or deleted drive/item id cached in the knowledge source config; an incorrectly constructed Graph URL from a malformed site/drive identifier.","solutions":["Check the status code in the message: retry with backoff if 429/5xx (Graph throttling is common on bulk operations)","Verify the driveId and itemId used in the Graph call still exist via GET /drives/{driveId}/items/{itemId}","Inspect console/server logs for the underlying Graph response body to see the detailed error code","Re-run the knowledge source sync after confirming the Graph API status at https://status.microsoft.com"],"exampleFix":"// before: single attempt, throws on 429\nconst item = await fetchDriveItem(connection, driveId, itemId, signal)\n// after: retry throttled/transient responses\nasync function fetchWithRetry(url: string, init: RequestInit, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    const res = await fetch(url, init)\n    if (res.status === 429 || res.status >= 500) {\n      await new Promise(r => setTimeout(r, 2 ** i * 1000))\n      continue\n    }\n    return res\n  }\n  throw new HTTPError(\"Failed to fetch SharePoint drive item after retries\", 400)\n}","handlingStrategy":"retry","validationCode":"// pre-flight: verify drive item accessibility\nconst head = await fetch(`https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}`, { headers: { Authorization: `Bearer ${token}` }, method: \"GET\" })\nif (!head.ok && head.status !== 404) throw new Error(`Graph pre-check failed: ${head.status}`)","typeGuard":null,"tryCatchPattern":"try {\n  await fetchDriveItem(conn, driveId, itemId, signal)\n} catch (e) {\n  if (e instanceof HTTPError && /Failed to fetch SharePoint drive item \\(429\\)|\\(5\\d\\d\\)/.test(e.message)) {\n    await sleep(backoff(attempt)); return retry()\n  }\n  throw e\n}","preventionTips":["Implement exponential backoff for 429/5xx Graph responses","Re-resolve drive/item ids from Graph at sync time instead of caching them long-term","Monitor Microsoft Graph service health during bulk operations"],"tags":["sharepoint","microsoft-graph","http","knowledge-source"],"backgroundTag":"upstream-http-error","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}