{"record":{"id":"be62deb74534cf54","repo":"Foundry376/Mailspring","slug":"o365-profile-request-failed-me-error-code-m","errorCode":null,"errorMessage":"O365 profile request failed: ${me.error.code}: ${me.error.message}","messagePattern":"O365 profile request failed: (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/internal_packages/onboarding/lib/onboarding-helpers.ts","lineNumber":300,"sourceCode":"      code_verifier: CODE_VERIFIER,\n      grant_type: `authorization_code`,\n      redirect_uri: `http://localhost:${LOCAL_SERVER_PORT}/desktop`,\n    }\n  );\n\n  // get the user's email address\n  const meResp = await fetch('https://graph.microsoft.com/v1.0/me', {\n    headers: { Authorization: `Bearer ${access_token}` },\n  });\n  const me = await meResp.json();\n  if (!meResp.ok) {\n    throw new Error(\n      `O365 profile request returned ${meResp.status} ${meResp.statusText}: ${JSON.stringify(me)}`\n    );\n  }\n  // The Graph API can return 200 OK with an error body in some edge cases\n  if (me.error) {\n    throw new Error(`O365 profile request failed: ${me.error.code}: ${me.error.message}`);\n  }\n\n  // Try multiple sources to find the email address. For most work accounts `mail` or\n  // `userPrincipalName` is set. For personal MSA accounts or accounts without Exchange\n  // Online licenses, fall back to the id_token claims (requires openid+email scopes).\n  let emailAddress: string | null = me.mail || me.userPrincipalName || null;\n\n  if (!emailAddress && id_token) {\n    try {\n      // Decode id_token JWT payload (base64url encoded) to extract email claims\n      const payload = JSON.parse(Buffer.from(id_token.split('.')[1], 'base64').toString('utf8'));\n      const candidate: string = payload.email || payload.preferred_username || payload.unique_name;\n      // Only accept values that look like real email addresses (not GUID-based UPNs)\n      if (candidate && /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(candidate)) {\n        emailAddress = candidate;\n      }\n    } catch {\n      // ignore token parsing errors","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/Foundry376/Mailspring/blob/648c685d602ece6bb00c22534b8734de6ac644b3/app/internal_packages/onboarding/lib/onboarding-helpers.ts#L282-L318","documentation":"Guard in buildMicrosoftAccountFromAuthResponse handling Microsoft Graph's quirk of returning HTTP 200 with an error object in the body: the me payload contains an error property, so the profile is treated as failed even though the status was ok. The thrown message surfaces the Graph error code and message.","triggerScenarios":"Thrown at app/internal_packages/onboarding/lib/onboarding-helpers.ts:300 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry onboarding — transient Graph errors (throttling, temporary auth propagation) often resolve","Verify scopes and token audience based on the embedded error code"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"648c685d602ece6bb00c22534b8734de6ac644b3","analyzedAt":"2026-09-03T02:00:24.311Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}