{"record":{"id":"95a6f2ee12ee5e3b","repo":"calcom/cal.diy","slug":"credentials-for-ics-feed-calendar-not-found","errorCode":null,"errorMessage":"Credentials for Ics Feed calendar not found.","messagePattern":"Credentials for Ics Feed calendar not found\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/calendars/services/ics-feed.service.ts","lineNumber":93,"sourceCode":"          teamId: credential.teamId,\n          appId: credential.appId,\n          invalid: credential.invalid,\n        },\n      };\n    } catch (e) {\n      this.logger.error(\"Could not add ICS feeds\", e);\n      throw new BadRequestException(\"Could not add ICS feeds, try using private ics feed.\");\n    }\n  }\n\n  async check(userId: number): Promise<{ status: typeof SUCCESS_STATUS }> {\n    const icsFeedCredentials = await this.credentialRepository.findCredentialByTypeAndUserId(\n      ICS_CALENDAR_TYPE,\n      userId\n    );\n\n    if (!icsFeedCredentials) {\n      throw new BadRequestException(\"Credentials for Ics Feed calendar not found.\");\n    }\n\n    if (icsFeedCredentials.invalid) {\n      throw new BadRequestException(\"Invalid Ics Feed credentials.\");\n    }\n\n    const { connectedCalendars } = await this.calendarsService.getCalendars(userId);\n    const icsCalendar = connectedCalendars.find(\n      (cal: { integration: { type: string } }) => cal.integration.type === ICS_CALENDAR_TYPE\n    );\n\n    if (!icsCalendar) {\n      throw new UnauthorizedException(\"Ics Feed not connected.\");\n    }\n    if (icsCalendar.error?.message) {\n      throw new UnauthorizedException(icsCalendar.error?.message);\n    }\n","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/calendars/services/ics-feed.service.ts#L75-L111","documentation":"Thrown by IcsFeedService.check, the connectivity-check handler. It calls credentialRepository.findCredentialByTypeAndUserId(ICS_CALENDAR_TYPE, userId); if no credential row of type 'ics_calendar' exists for that user, BadRequestException is raised because there is nothing to validate. This is a precondition gate before the more expensive getCalendars call.","triggerScenarios":"Calling GET /v2/calendars/ics/check (or check) for a user who has never saved an ICS feed via /save; passing a userId that belongs to a different user or environment; the credential was deleted between save and check; the type string passed is not exactly ICS_CALENDAR_TYPE.","commonSituations":"Frontend calls /check before the user has completed /save; a user removed the ICS integration from the webapp and the client still polls /check; test/dev environment with a different userId than the one that created the credential.","solutions":["Run POST /v2/calendars/ics/save first to create the ICS credential, then call /check.","Confirm the userId sent to /check is the same numeric user id returned by the save call.","If the credential was intentionally deleted, stop polling /check or treat a 400 here as 'not configured' rather than an error."],"exampleFix":"// before\nconst status = await api.get(`/v2/calendars/ics/check?userId=${userId}`);\n\n// after\nif (!icsCredentialExists) {\n  await api.post('/v2/calendars/ics/save', { userId, userEmail, urls });\n}\nconst status = await api.get(`/v2/calendars/ics/check?userId=${userId}`);","handlingStrategy":"validation","validationCode":"const cred = await credentialRepository.findCredentialByTypeAndUserId(ICS_CALENDAR_TYPE, userId);\nif (!cred) {\n  return { status: 'not_configured' }; // prompt user to save an ICS feed\n}","typeGuard":null,"tryCatchPattern":"try {\n  await icsFeedService.check(userId);\n} catch (e) {\n  if (e instanceof BadRequestException && e.message.includes('not found')) {\n    // treat as 'not configured' and trigger the save flow\n  } else throw e;\n}","preventionTips":["Only call /check after a successful /save.","Treat a 400 'not found' as a configuration step, not a transient error.","Pass the exact userId returned by the save call."],"tags":["ics","calendar","precondition","api-v2"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}