danny-avila/LibreChat · error · Error

Failed to obtain SharePoint access token

Error message

Failed to obtain SharePoint access token

What it means

Thrown when, after explicitly refetching the Graph token via `useSharePointToken`, the result still has no `access_token`. The token originates server-side: the client calls `/api/auth/graph-token?scopes=...` (requireJwtAuth), which reads `req.user.federatedTokens.access_token` and performs on-behalf-of exchange via `getGraphApiToken`. A missing token means either the backend rejected the request (400 missing scopes, 401 no federated token, 500 exchange failure) or the current user is not an Entra/OpenID user with federated credentials.

Source

Thrown at client/src/hooks/Files/useSharePointDownload.ts:56

      }

      setError(null);
      setDownloadProgress({ completed: 0, total: files.length, failed: [] });

      try {
        let accessToken = token?.access_token;
        if (!accessToken) {
          showToast({
            message: 'Getting SharePoint access token...',
            status: 'info',
            duration: 2000,
          });

          const tokenResult = await refetchToken();
          accessToken = tokenResult.data?.access_token;

          if (!accessToken) {
            throw new Error('Failed to obtain SharePoint access token');
          }
        }

        showToast({
          message: `Downloading ${files.length} file(s) from SharePoint...`,
          status: 'info',
          duration: 3000,
        });

        const downloadedFiles = await batchDownloadMutation.mutateAsync({
          files,
          accessToken,
          onProgress: (progress) => {
            setDownloadProgress(progress);

            if (files.length > 5 && progress.completed % 3 === 0) {
              showToast({
                message: `Downloaded ${progress.completed}/${progress.total} files...`,

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Confirm the user authenticated via OpenID/Entra (`user.provider === 'openid'`) — local/google users cannot get a Graph token through OBO.
  2. Check the server logs around `/api/auth/graph-token` for the specific 4xx/5xx and AADSTS error from `getGraphApiToken`.
  3. Verify the AAD app registration has the required Graph delegated permissions with admin consent, and that `SHAREPOINT_PICKER_GRAPH_SCOPE` is set to a valid scope string (e.g. `Files.Read.All`).
  4. If the user's federated refresh token expired, have them re-authenticate with the IdP to refresh `federatedTokens`.
Defensive patterns

Strategy: validation

Validate before calling

// Confirm prerequisites before attempting a SharePoint download
if (user?.provider !== 'openid') throw new Error('SharePoint download requires an Entra/OpenID session');
if (!startupConfig?.sharePointPickerGraphScope) throw new Error('SHAREPOINT_PICKER_GRAPH_SCOPE is not configured');

Type guard

function hasGraphToken(v: unknown): v is { access_token: string } {
  return typeof v === 'object' && v !== null && typeof (v as any).access_token === 'string' && (v as any).access_token.length > 0;
}

Try / catch

let accessToken = token?.access_token;
if (!accessToken) {
  const result = await refetchToken();
  accessToken = result.data?.access_token;
}
if (!accessToken) throw new Error('Failed to obtain SharePoint access token');

Prevention

When it happens

Trigger: The user is logged in via a non-OpenID provider (local/google) and has no `federatedTokens` to exchange; the backend's `getGraphApiToken` OBO call failed (Microsoft Graph/AADSTS error); `scopes` query param empty (400); the `sharePointPickerGraphScope` startup config is unset so the requested scope is invalid; user's refresh token expired and silent OBO failed.

Common situations: Enabling the SharePoint file picker for users who authenticated via local/email login (no federated token); AAD app registration missing the Graph API permissions/admin consent for the OBO scope; `SHAREPOINT_PICKER_GRAPH_SCOPE` / `SHAREPOINT_PICKER_SHAREPOINT_SCOPE` env unset or malformed; transient AADSTS errors during token exchange.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/c9def230166ef8c3. Report an issue: GitHub.