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

  1. Ensure the environment talks directly to graph.microsoft.com — do not rewrite Graph response bodies through a proxy.
  2. If a proxy is mandatory, make sure it preserves the absolute https://graph.microsoft.com next links.
  3. Update SHAREPOINT_API_BASE_URL if your deployment targets a sovereign/different Graph endpoint so next links match it.
  4. 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

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


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/a10fe42760443fba. Report an issue: GitHub.