Budibase/budibase · error

Could not refresh OAuth Token

Error message

Could not refresh OAuth Token

What it means

Same guard as the drive/list pagination checks: inside fetchSharePointCollection, any '@odata.nextLink' that is not an https URL on graph.microsoft.com/v1.0 causes this HTTPError. It prevents following pagination links that leave the trusted Graph API origin.

Source

Thrown at packages/backend-core/src/auth/auth.ts:70

// Strategies
_passport.use(new LocalStrategy(local.options, local.authenticate))

async function refreshOIDCAccessToken(
  chosenConfig: OIDCInnerConfig,
  refreshToken: string
): Promise<RefreshResponse> {
  const callbackUrl = await oidc.getCallbackUrl()
  let enrichedConfig: OIDCStrategyConfiguration
  let strategy: OpenIDConnectStrategy

  try {
    enrichedConfig = await oidc.fetchStrategyConfig(chosenConfig, callbackUrl)
    if (!enrichedConfig) {
      throw new Error("OIDC Config contents invalid")
    }
    strategy = await oidc.strategyFactory(enrichedConfig, ssoSaveUserNoOp)
  } catch (err) {
    throw new Error("Could not refresh OAuth Token")
  }

  refresh.use(strategy)

  return new Promise(resolve => {
    refresh.requestNewAccessToken(
      ConfigType.OIDC,
      refreshToken,
      (err: any, accessToken: string, refreshToken: any, params: any) => {
        resolve({ err, accessToken, refreshToken, params })
      }
    )
  })
}

async function refreshGoogleAccessToken(
  config: GoogleInnerConfig,
  refreshToken: any

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Route traffic directly to graph.microsoft.com without response-rewriting proxies.
  2. Validate your test/mock fixtures return absolute https://graph.microsoft.com/v1.0/... nextLinks.
  3. If a sovereign cloud is in use, note the allowlist only accepts the global cloud host.
  4. Log the offending nextLink and check it with new URL(link) to see which constraint (protocol/host/port/path) fails.
Defensive patterns

Strategy: validation

Validate before calling

const link = payload["@odata.nextLink"]
if (link && !/^https:\/\/graph\.microsoft\.com\/v1\.0\//.test(link)) {
  throw new Error(`Unexpected nextLink host: ${new URL(link, "https://graph.microsoft.com").hostname}`)
}

Type guard

const isGraphV1Url = (v: unknown): v is string =>
  typeof v === "string" && (() => { try { const u = new URL(v); return u.protocol === "https:" && u.hostname === "graph.microsoft.com" && u.pathname.startsWith("/v1.0/") } catch { return false } })()

Try / catch

try {
  await listSharePointLists(token, siteId)
} catch (e) {
  if (e instanceof Error && e.message === "Invalid SharePoint pagination URL") {
    // inspect proxy/mock layer for rewritten nextLinks
  } else throw e
}

Prevention

When it happens

Trigger: A lists/columns/items page response contains '@odata.nextLink' that is relative, http://, on a different hostname/port, or otherwise fails URL parsing against the SHAREPOINT_API_BASE allowlist.

Common situations: Proxy or gateway rewriting Graph response bodies; mocked Graph servers in tests returning relative nextLinks; sovereign-cloud endpoints with different hostnames; corrupted response payloads.

Related errors


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