nextcloud/server · error · Sabre\DAV\Exception\NotFound
Invalid node
Error message
Invalid node
What it means
CalendarObject::getName() derives the object name from the VCalendar's base component (X-FILENAME if set, otherwise UID.ics). getBaseComponent() returning null means the VCalendar built from the app backend's search() results contains no VEVENT/VTODO/VJOURNAL - invalid calendar data from the provider, as the inline comment states ('should never happen except the app provides invalid calendars'). Thrown as NotFound (HTTP 404).
Source
Thrown at apps/dav/lib/CalDAV/AppCalendar/CalendarObject.php:125
$components[$key]->STATUS = 'CANCELLED';
$components[$key]->SEQUENCE = isset($component->SEQUENCE) ? ((int)$component->SEQUENCE->getValue()) + 1 : 1;
if ($component->name === 'VEVENT') {
$components[$key]->METHOD = 'CANCEL';
}
}
$this->backend->createFromString($this->getName(), (new VCalendar($components))->serialize());
} else {
throw new Forbidden('This calendar-object is read-only');
}
}
#[\Override]
public function getName(): string {
// Every object is required to have an UID
$base = $this->vobject->getBaseComponent();
// This should never happen except the app provides invalid calendars (VEvent, VTodo... all require UID to be present)
if ($base === null) {
throw new NotFound('Invalid node');
}
if (isset($base->{'X-FILENAME'})) {
return (string)$base->{'X-FILENAME'};
}
return (string)$base->UID . '.ics';
}
#[\Override]
public function setName($name): void {
throw new Forbidden('This calendar-object is read-only');
}
#[\Override]
public function getLastModified(): ?int {
$base = $this->vobject->getBaseComponent();
if ($base !== null && $this->vobject->getBaseComponent()->{'LAST-MODIFIED'}) {
/** @var DateTime */
$lastModified = $this->vobject->getBaseComponent()->{'LAST-MODIFIED'};View on GitHub (pinned to ecdeb153ff)
Solutions
- Fix the provider so search() returns valid iCalendar objects whose base components (VEVENT/VTODO/VJOURNAL) carry a UID
- Validate the provider's search() output by parsing it with Sabre\VObject\Reader in the app's tests before shipping
- End users: report the issue to the app that provides the calendar - the DAV layer is only the messenger
Example fix
// before: provider returns fragments without a base component return ['UID' => 'abc', 'SUMMARY' => 'x']; // after: include a real base component with UID return ['UID' => 'abc', 'objects' => $veventWithData]; // ensures VCalendar has VEVENT base
Defensive patterns
Strategy: type-guard
Validate before calling
// Provider-side: validate search() output before exposing it
use Sabre\VObject\Reader;
foreach ($this->search('') as $index => $object) {
$v = Reader::read($object['objects'] ?? '', Reader::OPTION_IGNORE_ERRORS);
if ($v->getBaseComponent() === null) {
$this->logger->warning('Skipping object without base component at index ' . $index);
unset($objects[$index]);
}
} Type guard
function hasCalendarBaseComponent(Sabre\VObject\Component\VCalendar $v): bool {
return $v->getBaseComponent() !== null; // VEVENT/VTODO/VJOURNAL with UID present
} Try / catch
try {
$name = $object->getName();
} catch (Sabre\DAV\Exception\NotFound $e) {
// provider returned data without a base component; skip this object and report to the app
} Prevention
- App providers: guarantee every search() result contains a base component with a UID
- Parse provider output with Sabre\VObject\Reader in tests to catch invalid iCalendar early
- Filter invalid objects out before they reach the DAV layer instead of letting 404s surface
When it happens
Trigger: An app calendar provider whose search() returns objects without a base component (e.g. only VTIMEZONE definitions or malformed fragments), so any CalDAV operation that resolves the node's name (getChild, PROPFIND on children, PUT handling) fails.
Common situations: Buggy ICalendar implementations returning non-compliant search results; providers exposing raw data arrays missing the component keys; calendar apps updated with changed search() semantics.
Related errors
- Setting ACL is not supported on this node
- Deleting an entry is not implemented
- Creating a new entry is not allowed
- Node not found
- Setting ACL is not supported on this node
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/9f67736173cb2822.
Report an issue: GitHub.