calcom/cal.diy · warning · HttpError

You must be logged in to do this

Error message

You must be logged in to do this

What it means

Standard auth guard at the top of the Google Calendar OAuth-start handler. Fires as `HttpError` **401** when `req.session?.user` is absent. `defaultResponder` catches it and returns `{ message, url, method, data }` with status 401. This is expected behavior for unauthenticated requests, not a bug.

Source

Thrown at packages/app-store/googlecalendar/api/add.ts:16

import { OAuth2Client } from "googleapis-common";
import type { NextApiRequest, NextApiResponse } from "next";

import { GOOGLE_CALENDAR_SCOPES, SCOPE_USERINFO_PROFILE, WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";
import { HttpError } from "@calcom/lib/http-error";
import { defaultHandler } from "@calcom/lib/server/defaultHandler";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";

import { encodeOAuthState } from "../../_utils/oauth/encodeOAuthState";
import { getGoogleAppKeys } from "../lib/getGoogleAppKeys";

async function getHandler(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 { client_id, client_secret } = await getGoogleAppKeys();
  const redirect_uri = `${WEBAPP_URL_FOR_OAUTH}/api/integrations/googlecalendar/callback`;
  const oAuth2Client = new OAuth2Client(client_id, client_secret, redirect_uri);

  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: "offline",
    scope: [SCOPE_USERINFO_PROFILE, ...GOOGLE_CALENDAR_SCOPES],
    // A refresh token is only returned the first time the user
    // consents to providing access.  For illustration purposes,
    // setting the prompt to 'consent' will force this consent

View on GitHub (pinned to 176037d0af)

Solutions

  1. Ensure the user is signed in (redirect to login) before navigating to the install endpoint.
  2. On the client, check auth state before issuing the request and redirect to login on a 401.
  3. Confirm the session cookie is actually sent (SameSite/Secure, HTTPS, correct domain).
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: only navigate to the Google Calendar install URL when authenticated
function goToGoogleCalendarInstall() {
  if (!document.cookie.includes("next-auth.session-token") && !document.cookie.includes("__Secure-next-auth.session-token")) {
    window.location.href = "/auth/login?callbackUrl=" + encodeURIComponent(window.location.href);
    return;
  }
  window.location.href = "/api/integrations/googlecalendar/add";
}

Try / catch

// On the calling client, a 401 from /add should send the user to login
const res = await fetch("/api/integrations/googlecalendar/add");
if (res.status === 401) {
  window.location.href = `/auth/login?callbackUrl=${encodeURIComponent("/apps/installed")}`;
  return;
}

Prevention

When it happens

Trigger: A request to `/api/integrations/googlecalendar/add` without a valid session cookie — e.g. direct URL access, an expired session, a curl/automated request with no auth, or a browser that dropped the cookie.

Common situations: Session expired between page load and clicking Install Google Calendar; route opened directly in incognito/new tab; cookie stripped by a proxy or blocked by browser privacy settings.

Related errors


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