calcom/cal.diy · error · HttpError
Session user must have an email
Error message
Session user must have an email
What it means
Thrown as an HttpError (HTTP 400) by the Dub add handler when a logged-in session user has no email. NextAuth's session type does not guarantee email, and the Dub OAuth flow needs the user's email to attribute the link, so the handler explicitly asserts it. The inline TODO notes the typings are inaccurate.
Source
Thrown at packages/app-store/dub/api/add.ts:20
import { HttpError } from "@calcom/lib/http-error";
import { defaultHandler } from "@calcom/lib/server/defaultHandler";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import getParsedAppKeysFromSlug from "../../_utils/getParsedAppKeysFromSlug";
import { dubAppKeysSchema, scopeString } from "../lib/utils";
async function handler(req: NextApiRequest, res: NextApiResponse) {
const loggedInUser = req.session?.user;
if (!loggedInUser) {
throw new HttpError({ statusCode: 401, message: "You must be logged in to do this" });
}
// Ideally this should never happen, as email is there in session user but typings aren't accurate it seems
// TODO: So, confirm and later fix the typings
if (!loggedInUser.email) {
throw new HttpError({ statusCode: 400, message: "Session user must have an email" });
}
const { teamId } = req.query;
const { client_id, redirect_uris } = await getParsedAppKeysFromSlug("dub", dubAppKeysSchema);
const url = new URL("https://app.dub.co/oauth/authorize");
url.searchParams.append("client_id", client_id);
url.searchParams.append("redirect_uri", redirect_uris);
url.searchParams.append("response_type", "code");
url.searchParams.append("scope", scopeString);
if (typeof teamId === "string" && !Number.isNaN(Number(teamId))) {
url.searchParams.append("state", JSON.stringify({ teamId: Number(teamId) }));
}
const oauthUrl = url.toString();
return res.status(200).json({ url: oauthUrl });
}
View on GitHub (pinned to 176037d0af)
Solutions
- Ensure the NextAuth session callback includes email: return { ...session, user: { ...session.user, email: user.email } }.
- Confirm the user record in the DB actually has an email address.
- Verify NEXTAUTH_SECRET matches the one that issued the session (mismatch can produce partial sessions).
- Re-authenticate the affected user to refresh the session JWT.
Example fix
// before
if (!loggedInUser.email) {
throw new HttpError({ statusCode: 400, message: "Session user must have an email" });
}
// after - surface to the user, prompt re-login
if (!loggedInUser.email) {
throw new HttpError({ statusCode: 400, message: "Your session is missing an email. Please log out and sign in again." });
} Defensive patterns
Strategy: validation
Validate before calling
if (!loggedInUser || !loggedInUser.email) {
throw new HttpError({ statusCode: 400, message: "Session user must have an email" });
}
// Configure NextAuth session callback to always include email:
// callbacks: { session({ session, user }) { return { ...session, user: { ...session.user, email: user.email } }; } } Type guard
const hasSessionEmail = (u: unknown): u is { email: string } =>
typeof u === "object" && u !== null && typeof (u as any).email === "string" && (u as any).email.length > 0; Try / catch
if (!loggedInUser.email) {
// prompt re-authentication rather than opaque 400
res.redirect(`${WEBAPP_URL}/auth/login?error=missing_email`);
return;
} Prevention
- In the NextAuth session callback, always return user.email.
- Backfill missing emails in the user table.
- Keep NEXTAUTH_SECRET stable so session JWTs decode fully.
When it happens
Trigger: req.session.user is truthy but req.session.user.email is undefined or empty string. Possible with a custom NextAuth session strategy that omits email, a corrupt session JWT, or a user record missing an email in the database.
Common situations: Custom NextAuth callback that returns { id, name } without email; legacy user accounts with null email; session JWT decoded against a stale secret yielding partial claims.
Related errors
- You must be logged in to do this
- `code` must be a string
- You must be logged in to do this
- Invalid Access token.
- Invalid conferencing app, available apps are:
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/48351dbc11818866.
Report an issue: GitHub.