Budibase/budibase · error · HTTPError
Invalid SharePoint pagination URL
Error message
Invalid SharePoint pagination URL
What it means
While paging through Graph site results, each @odata.nextLink is validated by isAllowedSharePointNextLink, which requires the URL to match the Microsoft Graph base URL (protocol, host, port, path prefix). If a next link points anywhere else the code refuses to follow it — an SSRF/open-redirect protection — and throws a 400 HTTPError.
Source
Thrown at packages/server/src/sdk/workspace/ai/knowledgeSources/sharepoint/connection.ts:282
const payload = await fetchSitesPage(nextLink)
for (const site of payload.value || []) {
if (!site?.id) {
continue
}
sitesById.set(site.id, {
id: site.id,
name: site.displayName || site.name,
webUrl: site.webUrl,
})
}
const nextPageLink = payload?.["@odata.nextLink"]
if (!nextPageLink) {
nextLink = ""
continue
}
if (!isAllowedSharePointNextLink(nextPageLink)) {
throw new HTTPError("Invalid SharePoint pagination URL", 400)
}
nextLink = nextPageLink
}
if (nextLink) {
console.warn(
"Stopped fetching SharePoint sites due to reaching maximum page limit",
{
lastNextLink: nextLink,
}
)
}
return Array.from(sitesById.values()).sort((a, b) =>
(a.name || a.id).localeCompare(b.name || b.id)
)
}
export const fetchSharePointSitesByDatasourceAuthConfig = async (View on GitHub (pinned to a81a902e9a)
Solutions
- Ensure the environment talks directly to graph.microsoft.com — do not rewrite Graph response bodies through a proxy.
- If a proxy is mandatory, make sure it preserves the absolute https://graph.microsoft.com next links.
- Update SHAREPOINT_API_BASE_URL if your deployment targets a sovereign/different Graph endpoint so next links match it.
- Capture the offending nextLink from server logs to diagnose why validation failed.
Defensive patterns
Strategy: validation
Validate before calling
import { isAllowedSharePointNextLink } from "./connection"
// before following any next link yourself:
if (!isAllowedSharePointNextLink(nextLink)) {
throw new Error("Refusing to follow non-Graph pagination URL")
} Type guard
const isAbsoluteGraphUrl = (value: string): boolean => {
try {
const u = new URL(value)
return u.protocol === "https:" && u.hostname.endsWith("graph.microsoft.com")
} catch {
return false
}
} Try / catch
try {
await fetchSharePointSitesByDatasourceAuthConfig(datasourceId, authConfigId)
} catch (err) {
if (err instanceof HTTPError && err.message === "Invalid SharePoint pagination URL") {
// check proxy/EGRESS config rewriting graph.microsoft.com links
}
throw err
} Prevention
- Do not route Microsoft Graph traffic through proxies that rewrite response URLs.
- Keep SHAREPOINT_API_BASE_URL aligned with the Graph endpoint actually in use.
- If mocking Graph in tests, return absolute next links on the same host as the base URL.
When it happens
Trigger: A Graph response's @odata.nextLink is a relative URL, a different host (proxy/region redirect), or a malformed URL so isAllowedSharePointNextLink returns false.
Common situations: Environment reroutes Graph through a custom proxy/EGRESS host so next links come back with a different hostname; Graph changes pagination URL shape; mock/test Graph servers returning relative next links; corrupted or tampered responses.
Related errors
- Error getting status
- Could not refresh OAuth Token
- Invitation is not valid or has expired, please request a new
- 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/a10fe42760443fba.
Report an issue: GitHub.