calcom/cal.diy · error · UnauthorizedException

NextAuthStrategy - Email not found in the authentication tok

Error message

NextAuthStrategy - Email not found in the authentication token.

What it means

Thrown by NextAuthStrategy.authenticate when the decoded NextAuth session payload has no `email` claim. The token decoded (so the signature/secret is correct), but the session does not carry an email — Cal.com resolves users by email and cannot proceed without it.

Source

Thrown at apps/api/v2/src/modules/auth/strategies/next-auth/next-auth.strategy.ts:25

import { getToken } from "next-auth/jwt";

@Injectable()
export class NextAuthStrategy extends PassportStrategy(NextAuthPassportStrategy, "next-auth") {
  constructor(private readonly userRepository: UsersRepository, private readonly config: ConfigService) {
    super();
  }

  async authenticate(req: Request) {
    try {
      const nextAuthSecret = this.config.get("next.authSecret", { infer: true });
      const payload = await getToken({ req, secret: nextAuthSecret });

      if (!payload) {
        throw new UnauthorizedException("NextAuthStrategy - Authentication token is missing or invalid.");
      }

      if (!payload.email) {
        throw new UnauthorizedException("NextAuthStrategy - Email not found in the authentication token.");
      }

      const user = await this.userRepository.findByEmailWithProfile(payload.email);
      if (!user) {
        throw new UnauthorizedException(
          "NextAuthStrategy - User associated with the authentication token email not found."
        );
      }

      return this.success(user);
    } catch (error) {
      if (error instanceof Error) return this.error(error);
      return this.error(
        new InternalServerErrorException(
          "NextAuthStrategy - An error occurred while authenticating the request"
        )
      );
    }

View on GitHub (pinned to 176037d0af)

Solutions

  1. Review the NextAuth callbacks (jwt/session) to ensure `token.email` is set from `profile.email`.
  2. Force the user to re-authenticate so a complete session JWT is minted.
  3. If email is genuinely optional in your setup, authenticate by userId/sub instead.
Defensive patterns

Strategy: type-guard

Validate before calling

const payload = await getToken({ req, secret });
if (!payload?.email) throw new Error('Session JWT missing email; fix NextAuth callbacks or re-authenticate');

Type guard

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

Prevention

When it happens

Trigger: A logged-in session that was created without persisting the user's email into the JWT (custom NextAuth callbacks that drop the email), or a token minted with a different claims shape.

Common situations: Custom NextAuth `jwt`/`session` callbacks that forget to propagate `email`; anonymous/magic-link sessions that haven't completed email verification; switching identity providers mid-session.

Understand the failure class

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/36ac761b0fb0966b. Report an issue: GitHub.