calcom/cal.diy · error · UnauthorizedException
Invalid Access token.
Error message
Invalid Access token.
What it means
Thrown by OutlookService.saveCalendarCredentialsAndRedirect, the OAuth-callback handler for Office 365. After Microsoft redirects back with an OAuth code, the handler resolves the calling user via tokensService.getAccessTokenOwnerId(accessToken); if no user maps to the supplied Cal platform access token, UnauthorizedException('Invalid Access token.') is raised before the code is exchanged for Graph credentials (getOAuthCredentials). This is the Outlook twin of error 380 in the Google service.
Source
Thrown at apps/api/v2/src/platform/calendars/services/outlook.service.ts:184
redir?: string,
isDryRun?: boolean
) {
// if code is not defined, user denied to authorize office 365 app, just redirect straight away
if (!code || code === "undefined") {
return { url: redir || origin };
}
// if isDryRun is true we know its a dry run so we just redirect straight away
if (isDryRun) {
return { url: redir || origin };
}
const parsedCode = z.string().parse(code);
const ownerId = await this.tokensService.getAccessTokenOwnerId(accessToken);
if (!ownerId) {
throw new UnauthorizedException("Invalid Access token.");
}
const office365OAuthCredentials = await this.getOAuthCredentials(parsedCode);
const defaultCalendar = await this.getDefaultCalendar(office365OAuthCredentials.access_token);
if (defaultCalendar?.id) {
const alreadyExistingSelectedCalendar = await this.selectedCalendarsRepository.getUserSelectedCalendar(
ownerId,
OFFICE_365_CALENDAR_TYPE,
defaultCalendar.id
);
if (alreadyExistingSelectedCalendar) {
const isCredentialValid = await this.calendarsService.checkCalendarCredentialValidity(
ownerId,
alreadyExistingSelectedCalendar.credentialId ?? 0,
OFFICE_365_CALENDAR_TYPEView on GitHub (pinned to 176037d0af)
Solutions
- Re-authenticate with the Cal platform OAuth flow to obtain a fresh access token, then retry the Office 365 callback.
- Confirm the token being passed is the Cal platform access token (not the Microsoft OAuth code) and is delivered where the handler reads it.
- Ensure the deployment issuing the token and the deployment serving the callback are the same and share the signing secret/DB.
Example fix
// before
window.location.href = `${apiBase}/v2/calendars/office365/connect/callback?code=${msCode}`;
// after
// refresh calAccessToken first if it may have expired during consent
window.location.href = `${apiBase}/v2/calendars/office365/connect/callback?code=${msCode}`; Defensive patterns
Strategy: validation
Validate before calling
async function ensureTokenOwner(tokensService, accessToken) {
const ownerId = await tokensService.getAccessTokenOwnerId(accessToken);
if (!ownerId) return { ok: false, reason: 'Invalid Access token.' };
return { ok: true, ownerId };
} Type guard
function isNonEmptyToken(t: unknown): t is string {
return typeof t === 'string' && t.trim().length > 0 && t !== 'undefined';
} Try / catch
try {
await outlookService.saveCalendarCredentialsAndRedirect(code, accessToken, origin);
} catch (e) {
if (e instanceof UnauthorizedException && e.message === 'Invalid Access token.') {
// re-authenticate, then retry once
} else throw e;
} Prevention
- Refresh the Cal access token before the long Microsoft consent flow.
- Pass the Cal platform token (not the MS OAuth code) where the handler reads it.
- Keep issuing and callback deployments identical.
When it happens
Trigger: The /v2/calendars/office365/connect/callback (or equivalent) is called with an accessToken that is expired, revoked, belongs to another environment, or was never sent; the token is sent in the wrong location (query vs Authorization header); the user took long enough on Microsoft's consent screen that the Cal access token expired before the callback.
Common situations: Long Microsoft consent flow outlasting the Cal access-token TTL; token issued by a different Cal deployment (env mismatch); client passed the OAuth code as the access token or vice-versa; clock skew on the API host.
Related errors
- Invalid Access token.
- Credentials for office_365_calendar not found.
- Invalid office 365 calendar credentials.
- Office 365 calendar not connected.
- ${office365Calendar.error?.message}
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/767277441f5cadd9.
Report an issue: GitHub.