{"record":{"id":"58884b4757d1f25a","repo":"transloadit/uppy","slug":"unexpected-onedrive-token-refresh-response","errorCode":null,"errorMessage":"Unexpected OneDrive token refresh response","messagePattern":"Unexpected OneDrive token refresh response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/companion/src/server/provider/onedrive/index.ts","lineNumber":194,"sourceCode":"      'provider.onedrive.token.refresh.error',\n      async () => {\n        const body = await getOauthClient()\n          .post('oauth20_token.srf', {\n            responseType: 'json',\n            form: {\n              refresh_token: refreshToken,\n              grant_type: 'refresh_token',\n              client_id: clientId,\n              client_secret: clientSecret,\n              redirect_uri: redirectUri,\n            },\n          })\n          .json<Record<string, unknown>>()\n\n        const accessToken =\n          typeof body['access_token'] === 'string' ? body['access_token'] : null\n        if (!accessToken) {\n          throw new Error('Unexpected OneDrive token refresh response')\n        }\n        return { accessToken }\n      },\n    )\n  }\n\n  async #withErrorHandling<T>(tag: string, fn: () => Promise<T>): Promise<T> {\n    return withProviderErrorHandling({\n      fn,\n      tag,\n      providerName: OneDrive.oauthProvider,\n      isAuthError: (response) => response.statusCode === 401,\n      isUserFacingError: (response) =>\n        typeof response.statusCode === 'number' &&\n        [400, 403].includes(response.statusCode),\n      // onedrive gives some errors here that the user might want to know about\n      // e.g. these happen if you try to login to a users in an organization,\n      // without an Office365 licence or OneDrive account setup completed","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/companion/src/server/provider/onedrive/index.ts#L176-L212","documentation":"After POSTing to OneDrive's token refresh endpoint, the response is parsed and body['access_token'] must be a string. If it is absent or not a string, Companion throws 'Unexpected OneDrive token refresh response', indicating the OAuth refresh failed (typically an expired/revoked refresh token or bad client credentials) and Microsoft returned an error body instead of a token.","triggerScenarios":"Calling refreshToken() with a revoked or expired Microsoft refresh token; Microsoft identity platform returning { error: 'invalid_grant' }; OneDrive client id/secret mismatch in Companion config.","commonSituations":"User removed the app from their Microsoft account; admin revoked consent in Azure AD; COMPANION_ONEDRIVE_KEY/SECRET rotated or wrong; single-page session outliving the refresh token's validity.","solutions":["Force re-authentication for the user — an invalid_grant means the stored refresh token is no longer usable","Verify COMPANION_ONEDRIVE_KEY and COMPANIED_ONEDRIVE_SECRET (check exact env names in your Companion config) match the Azure app registration","Log the token response body to identify the OAuth error code Microsoft returns","Ensure redirect URIs and consent scopes in Azure match what Companion requests"],"exampleFix":"// before\nconst { accessToken } = await onedriveProvider.refreshToken({ refreshToken, companion })\n\n// after\ntry {\n  const { accessToken } = await onedriveProvider.refreshToken({ refreshToken, companion })\n} catch {\n  // refresh failed -> make the user sign in again\n  throw new ProviderAuthError('OneDrive session expired', 401)\n}","handlingStrategy":"try-catch","validationCode":"if (typeof refreshToken !== 'string' || refreshToken.length === 0) {\n  throw new ProviderAuthError('no refresh token', 401)\n}","typeGuard":"const hasRefreshToken = (s: unknown): s is { refreshToken: string } =>\n  typeof (s as { refreshToken?: unknown })?.refreshToken === 'string'","tryCatchPattern":"try { await provider.refreshToken(args) } catch (e) { if (e instanceof Error && e.message === 'Unexpected OneDrive token refresh response') { await restartMicrosoftOAuth() } throw e }","preventionTips":["Redirect to re-auth on first refresh failure rather than retrying","Keep Azure app credentials in sync","Monitor Microsoft identity platform error codes in logs"],"tags":["onedrive","oauth","refresh-token","invalid-grant","companion","microsoft"],"backgroundTag":"oauth-refresh-token-invalid","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}