{"record":{"id":"cfac5b69bca9a741","repo":"dotnet/aspnetcore","slug":"failed-to-retrieve-token-no-account-found","errorCode":null,"errorMessage":"Failed to retrieve token, no account found.","messagePattern":"Failed to retrieve token, no account found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/WebAssembly/Authentication.Msal/src/Interop/AuthenticationService.ts","lineNumber":191,"sourceCode":"    async getAccessToken(request?: AccessTokenRequestOptions): Promise<AccessTokenResult> {\n        try {\n            this.trace('getAccessToken', request);\n            const newToken = await this.getTokenCore(request?.scopes);\n            return {\n                status: AccessTokenResultStatus.Success,\n                token: newToken\n            };\n        } catch (e) {\n            return {\n                status: AccessTokenResultStatus.RequiresRedirect\n            };\n        }\n    }\n\n    async getTokenCore(scopes?: string[]): Promise<AccessToken | undefined> {\n        const account = this.getAccount();\n        if (!account) {\n            throw new Error('Failed to retrieve token, no account found.');\n        }\n\n        const silentRequest = {\n            redirectUri: this._settings.auth?.redirectUri,\n            account: account,\n            scopes: scopes || this._settings.defaultAccessTokenScopes\n        };\n\n        this.debug(`Provisioning a token silently for scopes '${silentRequest.scopes}'`)\n        this.trace('_msalApplication.acquireTokenSilent', silentRequest);\n        const response = await this._msalApplication.acquireTokenSilent(silentRequest);\n        this.trace('_msalApplication.acquireTokenSilent-response', response);\n\n        if (response.scopes.length === 0 || response.accessToken === '') {\n            throw new Error('Scopes not granted.');\n        }\n\n        const result = {","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/WebAssembly/Authentication.Msal/src/Interop/AuthenticationService.ts#L173-L209","documentation":"In the MSAL-backed Blazor WebAssembly authentication service, getTokenCore attempts to acquire an access token silently for the currently signed-in account. If getAccount() returns no account (the user is not signed in / their session was cleared), there is no account to pass to MSAL's acquireTokenSilent, so the service throws. This indicates an authentication-state mismatch: the code reached token acquisition without a signed-in account.","triggerScenarios":"Thrown at line 191 when this.getAccount() returns falsy inside getTokenCore, before constructing the silent token request. Triggered by an interactive token request when MSAL has no account in cache.","commonSituations":"The user's MSAL session expired or was cleared (cache eviction, browser storage wipe); calling token acquisition before login completes; redirect-based auth where the post-redirect account population race lost; same-site/cookie policies blocking the MSAL cache; the user manually signed out but the app still requested a token.","solutions":["Guard token requests behind a signed-in check; trigger an interactive login (loginPopup/loginRedirect) when no account exists.","Handle the thrown error by redirecting the user to authentication, then retrying the token request.","Verify MSAL cache storage (localStorage/sessionStorage) is not blocked by browser privacy settings.","Ensure the auth flow fully completes (await AuthenticationService) before requesting tokens."],"exampleFix":"// before\nconst token = await authService.getAccessToken(opts);\n// after\nconst status = await authService.getAccessToken(opts);\nif (status.status === 'requiresRedirect') {\n  await authService.signIn(returnUrl);\n  return;\n}\n// and in MSAL config, fall back to interactive when silent fails:\ntry { return await msal.acquireTokenSilent(req); }\ncatch { return await msal.acquireTokenPopup(req); }","handlingStrategy":"try-catch","validationCode":"// Before requesting a token, check for an account\nconst accounts = msalInstance.getAllAccounts();\nif (accounts.length === 0) {\n  // trigger interactive sign-in instead of acquiring silently\n  await msalInstance.loginRedirect(loginRequest);\n  return;\n}","typeGuard":"function hasAccount(accounts: any[]): boolean {\n  return Array.isArray(accounts) && accounts.length > 0;\n}","tryCatchPattern":"try {\n  return await authService.getTokenCore(scopes);\n} catch (e) {\n  if (/no account found/i.test((e as Error).message)) {\n    await msalInstance.loginPopup(loginRequest);\n    return await authService.getTokenCore(scopes);\n  }\n  throw e;\n}","preventionTips":["Gate token requests behind a signed-in check.","Fall back to interactive sign-in when no account exists.","Verify MSAL cache storage is not blocked by browser privacy settings.","Complete the auth flow (await it) before requesting tokens."],"tags":["blazor","wasm","authentication","msal","token","no-account"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}