{"record":{"id":"9b3dab17709a2c61","repo":"calcom/cal.diy","slug":"not-authenticated","errorCode":null,"errorMessage":"Not authenticated","messagePattern":"Not authenticated","errorType":"http","errorClass":"HttpError","httpStatus":401,"severity":"error","filePath":"apps/web/app/api/availability/calendar/route.ts","lineNumber":32,"sourceCode":"import notEmpty from \"@calcom/lib/notEmpty\";\nimport { SelectedCalendarRepository } from \"@calcom/features/selectedCalendar/repositories/SelectedCalendarRepository\";\nimport prisma from \"@calcom/prisma\";\n\nimport { buildLegacyRequest } from \"@lib/buildLegacyCtx\";\n\nconst selectedCalendarSelectSchema = z.object({\n  integration: z.string(),\n  externalId: z.string(),\n  credentialId: z.coerce.number(),\n  delegationCredentialId: z.string().nullish().default(null),\n  eventTypeId: z.coerce.number().nullish(),\n});\n\nasync function authMiddleware() {\n  const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });\n\n  if (!session?.user?.id) {\n    throw new HttpError({ statusCode: 401, message: \"Not authenticated\" });\n  }\n\n  const userRepo = new UserRepository(prisma);\n  const userWithCredentials = await userRepo.findUserWithCredentials({\n    id: session.user.id,\n  });\n\n  if (!userWithCredentials) {\n    throw new HttpError({ statusCode: 401, message: \"Not authenticated\" });\n  }\n\n  return userWithCredentials;\n}\n\n// 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\nasync function getHandler() {\n  const user = await authMiddleware();\n","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/web/app/api/availability/calendar/route.ts#L14-L50","documentation":"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.","triggerScenarios":"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).","commonSituations":"Session cookie expired, third-party cookie blocking, fetch without credentials:'include', user logged out in another tab.","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."],"exampleFix":"// before\nawait fetch('/api/availability/calendar'); // no credentials\n\n// after\nconst res = await fetch('/api/availability/calendar', { credentials: 'include' });\nif (res.status === 401) { router.push('/auth/login'); return; }","handlingStrategy":"validation","validationCode":"// Ensure a session exists before calling the endpoint\nconst session = await getSession();\nif (!session?.user?.id) {\n  router.push('/auth/login');\n  return;\n}\nawait fetch('/api/availability/calendar', { credentials: 'include' });","typeGuard":"function hasSessionUserId(s: unknown): s is { user: { id: number } } {\n  return !!s && typeof s === 'object' &&\n    typeof (s as any).user?.id === 'number';\n}","tryCatchPattern":"try {\n  await fetch('/api/availability/calendar', { credentials: 'include' });\n} catch (e) {\n  if (e instanceof HttpError && e.statusCode === 401) {\n    router.push('/auth/login');\n    return;\n  }\n  throw e;\n}","preventionTips":["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)."],"tags":["auth","session","availability","calendar","unauthorized"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}