Budibase/budibase · error

Error getting account by tenantId ${tenantId}

Error message

Error getting account by tenantId ${tenantId}

What it means

listSharePointDrives pages through GET /v1.0/sites/{siteId}/drives. If any page returns a non-ok status other than 401/403 (which get a dedicated message), it throws 'Failed to list SharePoint drives (<status>)'. The status code in the message is the raw Microsoft Graph HTTP status after built-in retries of 429/5xx.

Source

Thrown at packages/backend-core/src/accounts/accounts.ts:57

export const getAccountByTenantId = async (
  tenantId: string
): Promise<CloudAccount | undefined> => {
  if (EXIT_EARLY) {
    return
  }
  const payload = {
    tenantId,
  }
  const response = await api.post(`/api/accounts/search`, {
    body: payload,
    headers: {
      [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
    },
  })

  if (response.status !== 200) {
    throw new Error(`Error getting account by tenantId ${tenantId}`)
  }

  const json: CloudAccount[] = await response.json()
  return json[0]
}

export const getStatus = async (): Promise<
  HealthStatusResponse | undefined
> => {
  if (EXIT_EARLY) {
    return
  }
  const response = await api.get(`/api/status`, {
    headers: {
      [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
    },
  })
  const json = await response.json()

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Check the HTTP status in the message: 404 means the siteId no longer exists — re-select the site so a fresh ID is stored.
  2. Verify the site is still accessible at https://<tenant>.sharepoint.com and its Graph ID via GET /v1.0/sites?search=.
  3. For 429/5xx, wait and retry later; the code already retries 429/500/502/503/504 up to 3 times with backoff.
  4. Confirm the bearer token's scope covers the target site (Sites.Read.All application permission with admin consent).

Example fix

// before
await listSharePointDrives(token, staleSiteId) // 404 -> "Failed to list SharePoint drives (404)"
// after
const sites = await fetchSharePointSitesByDatasourceAuthConfig(datasourceId, authConfigId)
const current = sites.find(s => s.name === siteName)
await listSharePointDrives(token, current.id) // fresh site ID
Defensive patterns

Strategy: try-catch

Validate before calling

const status = Number(String(err.message).match(/\((\d+)\)$/)?.[1])
if (status === 404) {
  // site deleted: refresh the site selection before retrying
}

Type guard

const isSharePointHttpError = (e: unknown): e is { message: string; status: number } =>
  typeof e === "object" && e !== null && "status" in e && typeof (e as { status: unknown }).status === "number"

Try / catch

try {
  const drives = await listSharePointDrives(token, siteId)
} catch (e) {
  if (isSharePointHttpError(e) && e.status === 400 && /drives \(404\)/.test(e.message)) {
    // re-resolve site ID, then retry once
  } else throw e
}

Prevention

When it happens

Trigger: fetch to graph.microsoft.com/v1.0/sites/{siteId}/drives?$top=200 returns e.g. 404 (site not found), 400 (bad siteId), or a persistent 5xx/429 after retries.

Common situations: Site ID from a previous sync was deleted/renamed in SharePoint; malformed or URL-encoded siteId; transient Graph outages that exhausted the 3-retry budget; tenant throttling beyond Retry-After handling.

Related errors


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