calcom/cal.diy · error · HttpError

Not authenticated

Error message

Not authenticated

What it means

Thrown by authMiddleware in /api/availability/calendar (HttpError, HTTP 401) when getServerSession returns no session or session.user.id. It is the first auth gate: the request carried no valid (or expired) session cookie, so the caller is anonymous.

Source

Thrown at apps/web/app/api/availability/calendar/route.ts:32

import notEmpty from "@calcom/lib/notEmpty";
import { SelectedCalendarRepository } from "@calcom/features/selectedCalendar/repositories/SelectedCalendarRepository";
import prisma from "@calcom/prisma";

import { buildLegacyRequest } from "@lib/buildLegacyCtx";

const selectedCalendarSelectSchema = z.object({
  integration: z.string(),
  externalId: z.string(),
  credentialId: z.coerce.number(),
  delegationCredentialId: z.string().nullish().default(null),
  eventTypeId: z.coerce.number().nullish(),
});

async function authMiddleware() {
  const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });

  if (!session?.user?.id) {
    throw new HttpError({ statusCode: 401, message: "Not authenticated" });
  }

  const userRepo = new UserRepository(prisma);
  const userWithCredentials = await userRepo.findUserWithCredentials({
    id: session.user.id,
  });

  if (!userWithCredentials) {
    throw new HttpError({ statusCode: 401, message: "Not authenticated" });
  }

  return userWithCredentials;
}

// TODO: It doesn't seem to be used from within the app. It is possible that someone outside Cal.diy is using this GET endpoint
async function getHandler() {
  const user = await authMiddleware();

View on GitHub (pinned to 176037d0af)

Solutions

  1. Ensure the client is authenticated (redirect to login) before calling the endpoint.
  2. Send credentials with the request (credentials: 'include' / same-origin fetch).
  3. On 401, refresh the session / re-authenticate and retry once.

Example fix

// before
await fetch('/api/availability/calendar'); // no credentials

// after
const res = await fetch('/api/availability/calendar', { credentials: 'include' });
if (res.status === 401) { router.push('/auth/login'); return; }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a session exists before calling the endpoint
const session = await getSession();
if (!session?.user?.id) {
  router.push('/auth/login');
  return;
}
await fetch('/api/availability/calendar', { credentials: 'include' });

Type guard

function hasSessionUserId(s: unknown): s is { user: { id: number } } {
  return !!s && typeof s === 'object' &&
    typeof (s as any).user?.id === 'number';
}

Try / catch

try {
  await fetch('/api/availability/calendar', { credentials: 'include' });
} catch (e) {
  if (e instanceof HttpError && e.statusCode === 401) {
    router.push('/auth/login');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: GET/POST /api/availability/calendar with no session cookie, an expired session, or a request from a logged-out client (e.g. a background fetch after session timeout).

Common situations: Session cookie expired, third-party cookie blocking, fetch without credentials:'include', user logged out in another tab.

Understand the failure class

Related errors


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