calcom/cal.diy · error · UnauthorizedException

${icsCalendar.error?.message}

Error message

${icsCalendar.error?.message}

What it means

The last guard in IcsFeedService.check: the connected calendar entry was found, but it carries an `error.message` (set by the calendar-integration layer when a live fetch against the feed failed: auth error, 404, parse error). That upstream message is forwarded verbatim inside UnauthorizedException, so the exact text depends on what the ICS adapter reported. This is a pass-through of the real upstream failure.

Source

Thrown at apps/api/v2/src/platform/calendars/services/ics-feed.service.ts:109

    if (!icsFeedCredentials) {
      throw new BadRequestException("Credentials for Ics Feed calendar not found.");
    }

    if (icsFeedCredentials.invalid) {
      throw new BadRequestException("Invalid Ics Feed credentials.");
    }

    const { connectedCalendars } = await this.calendarsService.getCalendars(userId);
    const icsCalendar = connectedCalendars.find(
      (cal: { integration: { type: string } }) => cal.integration.type === ICS_CALENDAR_TYPE
    );

    if (!icsCalendar) {
      throw new UnauthorizedException("Ics Feed not connected.");
    }
    if (icsCalendar.error?.message) {
      throw new UnauthorizedException(icsCalendar.error?.message);
    }

    return {
      status: SUCCESS_STATUS,
    };
  }
}

View on GitHub (pinned to 176037d0af)

Solutions

  1. Read the forwarded message string; it names the actual upstream problem (e.g. '401 Unauthorized', 'invalid ics').
  2. Re-save with the current private ICS URL via POST /v2/calendars/ics/save to replace the failing credential.
  3. Open the feed URL directly in a browser/curl to confirm it returns a valid .ics before re-saving.
Defensive patterns

Strategy: try-catch

Validate before calling

const { connectedCalendars } = await calendarsService.getCalendars(userId);
const ics = connectedCalendars.find(c => c.integration.type === ICS_CALENDAR_TYPE);
if (ics?.error?.message) {
  // surface ics.error.message to the user and offer re-save
}

Try / catch

try {
  await icsFeedService.check(userId);
} catch (e) {
  if (e instanceof UnauthorizedException) {
    // e.message is the upstream cause; if it mentions auth/401, re-save the feed
  } else throw e;
}

Prevention

When it happens

Trigger: The ICS feed is reachable but returns 401/403 (auth needed), the URL 404s, the feed body is not parseable ICS, or the upstream returned a transient 5xx that Cal recorded as the calendar's error state. The exact message is whatever the adapter set on connectedCalendar.error.message.

Common situations: Provider rotated the secret ICS link; public link became rate-limited; feed moved behind a login; TLS or DNS hiccup recorded as a permanent error in the connected-calendar row.

Related errors


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