{"record":{"id":"62bedc8d0507202d","repo":"siyuan-note/siyuan","slug":"caldav-calendar-path-is-invalid","errorCode":null,"errorMessage":"CalDAV: calendar path is invalid","messagePattern":"CalDAV: calendar path is invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/caldav.go","lineNumber":84,"sourceCode":"\tcalendarSupportedComponentSet       = []string{\"VEVENT\", \"VTODO\"}\n\n\tdefaultCalendar = caldav.Calendar{\n\t\tPath:                  CalDavDefaultCalendarPath,\n\t\tName:                  CalDavDefaultCalendarName,\n\t\tDescription:           \"Default calendar\",\n\t\tMaxResourceSize:       calendarMaxResourceSize,\n\t\tSupportedComponentSet: calendarSupportedComponentSet,\n\t}\n\tcalendars = Calendars{\n\t\tloaded:            false,\n\t\tchanged:           false,\n\t\tlock:              sync.Mutex{},\n\t\tcalendars:         sync.Map{},\n\t\tcalendarsMetaData: []*caldav.Calendar{},\n\t}\n\n\tErrorCalDavCalendarNotFound    = errors.New(\"CalDAV: calendar not found\")\n\tErrorCalDavCalendarPathInvalid = errors.New(\"CalDAV: calendar path is invalid\")\n\n\tErrorCalDavCalendarObjectNotFound    = errors.New(\"CalDAV: calendar object not found\")\n\tErrorCalDavCalendarObjectPathInvalid = errors.New(\"CalDAV: calendar object path is invalid\")\n)\n\n// CalendarsMetaDataFilePath returns the absolute path of the calendars' meta data file\nfunc CalendarsMetaDataFilePath() string {\n\treturn DavPath2DirectoryPath(CalDavCalendarsMetaDataFilePath)\n}\n\nfunc GetCalDavPathDepth(urlPath string) CalDavPathDepth {\n\turlPath = PathCleanWithSlash(urlPath)\n\treturn CalDavPathDepth(len(strings.Split(urlPath, \"/\")) - 1)\n}\n\n// GetCardDavPathDepth parses\nfunc ParseCalendarObjectPath(objectPath string) (calendarPath string, objectID string, err error) {\n\tcalendarPath, objectFileName := path.Split(objectPath)","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/caldav.go#L66-L102","documentation":"ErrorCalDavCalendarPathInvalid is returned by ParseCalendarObjectPath / calendar path parsing when the depth of the given CalDAV path does not match calDavPathDepth_Calendar, i.e. the path has too few or too many segments to identify a calendar.","triggerScenarios":"Calling ParseCalendarObjectPath (or handlers using it) with a calendar path whose GetCalDavPathDepth result differs from calDavPathDepth_Calendar.","commonSituations":"Client building URLs manually and omitting or duplicating path segments; mixing up calendar-object paths (deeper) with calendar paths; trailing/missing slashes changing segment counts.","solutions":["Use the exact path shape returned by ListCalendars instead of constructing it manually","Check GetCalDavPathDepth on the path before calling","Normalize stray leading/trailing slashes that alter segment depth"],"exampleFix":"// before\nParseCalendarObjectPath(\"/dav/caldav\")\n// after\nParseCalendarObjectPath(\"/dav/caldav/calendars/mycal/\") // correct depth","handlingStrategy":"validation","validationCode":"if GetCalDavPathDepth(path) != calDavPathDepth_Calendar {\n    return fmt.Errorf(\"refusing: %q is not a calendar-depth path\", path)\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, ErrorCalDavCalendarPathInvalid) {\n    // log the offending path and return 400 to the CalDAV client\n}","preventionTips":["Build calendar URLs from server-returned hrefs only","Keep a single URL-builder helper so segment counts stay consistent","Watch out for trailing-slash handling that changes depth"],"tags":["caldav","url","validation"],"backgroundTag":"invalid-url-format","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}