{"record":{"id":"a705bae46b57b56c","repo":"calcom/cal.diy","slug":"apiauthstrategy-next-auth-email-not-found-in-t","errorCode":null,"errorMessage":"ApiAuthStrategy - next auth - Email not found in the authentication token.","messagePattern":"ApiAuthStrategy - next auth - Email not found in the authentication token\\.","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"apps/api/v2/src/modules/auth/strategies/api-auth/api-auth.strategy.ts","lineNumber":303,"sourceCode":"      );\n    }\n\n    const user: UserWithProfile | null = await this.userRepository.findByIdWithProfile(ownerId);\n    if (!user) {\n      throw new UnauthorizedException(\n        \"ApiAuthStrategy - access token - User associated with the access token not found.\"\n      );\n    }\n\n    const organizationId = this.usersService.getUserMainOrgId(user) as number;\n    request.organizationId = organizationId;\n\n    return user;\n  }\n\n  async nextAuthStrategy(token: { email?: string | null }, request: ApiAuthGuardRequest) {\n    if (!token.email) {\n      throw new UnauthorizedException(\n        \"ApiAuthStrategy - next auth - Email not found in the authentication token.\"\n      );\n    }\n\n    const user = await this.userRepository.findByEmailWithProfile(token.email);\n    if (!user) {\n      throw new UnauthorizedException(\n        \"ApiAuthStrategy - next auth - User associated with the authentication token email not found.\"\n      );\n    }\n    const organizationId = this.usersService.getUserMainOrgId(user) as number;\n    request.organizationId = organizationId;\n\n    return user;\n  }\n\n  async validateThirdPartyAccessToken(\n    token: string,","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/auth/strategies/api-auth/api-auth.strategy.ts#L285-L321","documentation":"Thrown by ApiAuthStrategy.nextAuthStrategy when the decoded NextAuth JWT has no `email` claim. The guard took the next-auth path (Bearer that is not an API key and not an OAuth access token) and decoded a session token, but the resulting payload lacks an email — Cal.com keys users by email, so it cannot resolve the principal.","triggerScenarios":"Sending a NextAuth session JWT (the cookie from app.cal.com) as a Bearer token to /v2 when that token's payload has no email (anonymous session, custom JWT, or a token from a different NextAuth instance whose secret differs).","commonSituations":"Grabbing the wrong cookie value; sending an unauthenticated NextAuth token; mismatch between the JWT signing secret used to mint the token and the API's next.authSecret env var (decoding succeeds but claims are partial).","solutions":["Use the platform OAuth flow (access token) or a static API key instead of the NextAuth session cookie for API calls.","If you must use NextAuth, ensure the session was created with the same `next.authSecret` and includes the user's email claim.","Log in to the web app first so the session cookie is fully populated before extracting it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const payload = decodeJwt(sessionJwt);\nif (!payload?.email) throw new Error('Session token has no email claim; re-authenticate via the web app');","typeGuard":"function hasEmailClaim(p: unknown): p is { email: string } {\n  return typeof p === 'object' && p !== null && typeof (p as any).email === 'string' && (p as any).email.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Use platform OAuth access tokens or API keys for /v2 calls instead of NextAuth session cookies.","Ensure NextAuth jwt/session callbacks propagate the user's email claim.","Reject anonymous/partial sessions before they reach protected routes."],"tags":["auth","next-auth","jwt","platform"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}