calcom/cal.diy · error · BadRequestException
Listed cals and URLs mismatch: ${listedCals.length} vs. ${ur
Error message
Listed cals and URLs mismatch: ${listedCals.length} vs. ${urls.length} What it means
Raised inside IcsFeedService.save after BuildIcsFeedCalendarService(...).listCalendars() returns. The service is given N ICS feed URLs (urls.length) and expects the DAV/ICS adapter to enumerate exactly that many calendars; a count mismatch means one or more feeds could not be resolved (unreachable, unparseable, or merged), so the whole credential-upsert is aborted with BadRequestException. The error message echoes the two counts so you can see which side is short.
Source
Thrown at apps/api/v2/src/platform/calendars/services/ics-feed.service.ts:56
userId: userId,
teamId: null,
appId: ICS_CALENDAR,
invalid: false,
delegationCredentialId: null,
encryptedKey: null,
};
try {
const dav = BuildIcsFeedCalendarService({
id: 0,
...data,
user: { email: userEmail },
});
const listedCals = await dav.listCalendars();
if (listedCals.length !== urls.length) {
throw new BadRequestException(
`Listed cals and URLs mismatch: ${listedCals.length} vs. ${urls.length}`
);
}
const credential = await this.credentialRepository.upsertUserAppCredential(
ICS_CALENDAR_TYPE,
data.key,
userId
);
await this.calendarsCacheService.deleteConnectedAndDestinationCalendarsCache(userId);
return {
status: SUCCESS_STATUS,
data: {
id: credential.id,
type: credential.type,
userId: credential.userId,View on GitHub (pinned to 176037d0af)
Solutions
- Fetch each URL in urls[] with curl -I and confirm a 200 with content-type text/calendar before calling /v2/calendars/ics/save.
- Use the 'private'/'secret address in iCal format' link for every entry (Google: calendar Settings -> Integrate calendar -> Secret address).
- Reduce urls[] to a single URL to isolate which feed is shorting the count, then add the rest back one by one.
- If all feeds are valid but still mismatch, retry once; a transient network error during listCalendars can shrink listedCals without throwing.
Example fix
// before
await api.post('/v2/calendars/ics/save', { urls: [gcalPublicPageUrl, privateIcsUrl] });
// after
await api.post('/v2/calendars/ics/save', { urls: [privateIcsUrl] }); Defensive patterns
Strategy: validation
Validate before calling
async function preflightIcsUrls(urls: string[]) {
for (const u of urls) {
const res = await fetch(u, { method: 'GET' });
const ct = res.headers.get('content-type') || '';
if (!res.ok || !/text\/calendar|ics/.test(ct)) {
throw new Error(`Bad ICS feed ${u}: status=${res.status} content-type=${ct}`);
}
}
}
await preflightIcsUrls(urls); Type guard
function isIcsUrlList(urls: unknown): urls is string[] {
return Array.isArray(urls) && urls.length > 0 && urls.every(u => typeof u === 'string' && /^https?:\/\//.test(u));
} Try / catch
try {
await icsFeedService.save(userId, userEmail, urls, readonly);
} catch (e) {
if (e instanceof BadRequestException && e.message.startsWith('Listed cals and URLs mismatch')) {
// isolate the failing URL by retrying one at a time
} else throw e;
} Prevention
- Always use the provider's 'secret address in iCal format' link.
- Preflight each URL with a HEAD/GET to confirm 200 + text/calendar before saving.
- Save one URL at a time when debugging a mismatch.
When it happens
Trigger: POSTing an array of ICS URLs where at least one URL 404s, returns non-ICS content, requires auth that wasn't supplied, or is a duplicate that the DAV library collapses into one entry; a URL that is reachable but contains zero VEVENT calendars; a network/timeout during listCalendars that returns a partial list without throwing.
Common situations: Public Google/Outlook ICS links that require an authenticated session, or that rate-limit the server IP; feed URLs behind a CDN that serve an HTML login page instead of .ics; copy-paste of the calendar's HTML page URL instead of the 'secret address in iCal format'; feed temporarily down at save time.
Related errors
- Booking with uid ${bookingUid} not found
- Could not add ICS feeds, try using private ics feed.
- Credentials for Ics Feed calendar not found.
- Invalid Ics Feed credentials.
- Ics Feed not connected.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/21428f1b8409bb2d.
Report an issue: GitHub.