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
- Ensure the client is authenticated (redirect to login) before calling the endpoint.
- Send credentials with the request (credentials: 'include' / same-origin fetch).
- 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
- Always send credentials: 'include' (or rely on same-origin).
- Redirect to login when no session is present before invoking protected routes.
- Handle session-expiry globally (e.g. a fetch interceptor on 401).
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthorized
- Unauthorized
- NextAuthStrategy - Authentication token is missing or invali
- Invalid Access token.
- Invalid Access token.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/9b3dab17709a2c61.
Report an issue: GitHub.