{"record":{"id":"8ff2331a799cab85","repo":"nextcloud/server","slug":"a-valid-calendar-object-must-contain-at-least-one","errorCode":null,"errorMessage":"A valid calendar object must contain at least one VJOURNAL, VEVENT, or VTODO component type","messagePattern":"A valid calendar object must contain at least one VJOURNAL, VEVENT, or VTODO component type","errorType":"exception","errorClass":"Sabre\\DAV\\Exception\\BadRequest","httpStatus":400,"severity":"error","filePath":"apps/dav/lib/CalDAV/CalDavBackend.php","lineNumber":3429,"sourceCode":"\t *   * lastOccurence\n\t *   * uid - value of the UID property\n\t *\n\t * @param string $calendarData\n\t * @return array\n\t */\n\tpublic function getDenormalizedData(string $calendarData): array {\n\n\t\t$derived = [\n\t\t\t'etag' => md5($calendarData),\n\t\t\t'size' => strlen($calendarData),\n\t\t];\n\t\t// validate data and extract base component\n\t\t/** @var VCalendar $vObject */\n\t\t$vObject = Reader::read($calendarData);\n\t\t/** @var \\Sabre\\VObject\\Component\\VEvent[]|\\Sabre\\VObject\\Component\\VTodo[]|\\Sabre\\VObject\\Component\\VJournal[] $components */\n\t\t$components = $vObject->getBaseComponents();\n\t\tif (count($components) !== 1) {\n\t\t\tthrow new BadRequest('A valid calendar object must contain at least one VJOURNAL, VEVENT, or VTODO component type');\n\t\t}\n\t\t$component = $components[0];\n\t\t// extract basic information\n\t\t$derived['componentType'] = $component->name;\n\t\t$derived['uid'] = $component->UID ? $component->UID->getValue() : null;\n\t\t$derived['classification'] = $component->CLASS ? match ($component->CLASS->getValue()) {\n\t\t\t'PUBLIC' => self::CLASSIFICATION_PUBLIC,\n\t\t\t'CONFIDENTIAL' => self::CLASSIFICATION_CONFIDENTIAL,\n\t\t\tdefault => self::CLASSIFICATION_PRIVATE,\n\t\t} : self::CLASSIFICATION_PUBLIC;\n\t\t// extract start and end dates\n\t\t// VTODO components can have no start date\n\t\t/** @var  */\n\t\t$startDate = $component->DTSTART instanceof \\Sabre\\VObject\\Property\\ICalendar\\DateTime ? $component->DTSTART->getDateTime() : null;\n\t\t$endDate = $startDate ? clone $startDate : null;\n\t\tif ($startDate) {\n\t\t\t// Recurring\n\t\t\tif ($component->RRULE || $component->RDATE) {","sourceCodeStart":3411,"sourceCodeEnd":3447,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/CalDAV/CalDavBackend.php#L3411-L3447","documentation":"Error \"A valid calendar object must contain at least one VJOURNAL, VEVENT, or VTODO component type\" thrown in nextcloud/server.","triggerScenarios":"Thrown at apps/dav/lib/CalDAV/CalDavBackend.php:3429 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}