nextcloud/server · error · Sabre\DAV\Exception\BadRequest
{http://nextcloud.com/ns}prop-filter or {http://nextcloud.co
Error message
{http://nextcloud.com/ns}prop-filter or {http://nextcloud.com/ns}param-filter given without any {http://nextcloud.com/ns}comp-filter What it means
Structural check in CalendarSearchReport::xmlDeserialize(): the parsed filter contains prop-filters or param-filters but no comp-filter, so the server cannot know which component type (VEVENT/VTODO/VJOURNAL) to search and answers Sabre\DAV\Exception\BadRequest (HTTP 400). prop-filter and param-filter are only meaningful nested under a comp-filter.
Source
Thrown at apps/dav/lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php:137
break;
case '{' . SearchPlugin::NS_Nextcloud . '}limit':
$newProps['limit'] = $elem['value'];
break;
case '{' . SearchPlugin::NS_Nextcloud . '}offset':
$newProps['offset'] = $elem['value'];
break;
}
}
if (empty($newProps['filters'])) {
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}filter element is required for this request');
}
$propsOrParamsDefined = (!empty($newProps['filters']['props']) || !empty($newProps['filters']['params']));
$noCompsDefined = empty($newProps['filters']['comps']);
if ($propsOrParamsDefined && $noCompsDefined) {
throw new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter given without any {' . SearchPlugin::NS_Nextcloud . '}comp-filter');
}
if (!isset($newProps['filters']['search-term'])) {
throw new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}search-term is required for this request');
}
if (empty($newProps['filters']['props']) && empty($newProps['filters']['params'])) {
throw new BadRequest('At least one{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter is required for this request');
}
$obj = new self();
foreach ($newProps as $key => $value) {
$obj->$key = $value;
}
return $obj;
}
}
View on GitHub (pinned to ecdeb153ff)
Solutions
- Add a comp-filter naming the component type around/next to your prop and param filters
- Default the component selector to VEVENT in your UI when the user does not choose
- Validate the filter tree client-side: props/params present implies at least one comps entry
Example fix
// before <n:filter> <n:prop-filter name="SUMMARY"/> <n:search-term>meeting</n:search-term> </n:filter> // after <n:filter> <n:comp-filter name="VEVENT"/> <n:prop-filter name="SUMMARY"/> <n:search-term>meeting</n:search-term> </n:filter>
Defensive patterns
Strategy: validation
Validate before calling
$hasComps = $comps !== [];
$hasPropsOrParams = $props !== [] || $params !== [];
if ($hasPropsOrParams && !$hasComps) {
$comps = ['VEVENT']; // or throw: prop/param filters require a comp-filter
} Type guard
function isValidFilterShape(array $comps, array $props, array $params): bool {
return ($props === [] && $params === []) || $comps !== [];
} Try / catch
try {
$client->request('REPORT', $calendarUri, $xmlBody);
} catch (\Sabre\Http\ClientException $e) {
if ($e->getResponse()?->getStatus() === 400) { /* add comp-filter for the component type */ }
} Prevention
- Model the filter as comps -> props -> params tree in code so structure cannot be flat
- Default component type to VEVENT in search UIs
- Validate the tree shape before serialization
When it happens
Trigger: Sending <n:filter><n:prop-filter name="SUMMARY"/><n:search-term>x</n:search-term></n:filter> without a <n:comp-filter name="VEVENT"/>.
Common situations: Client search forms that let users pick properties but no component type; copy-pasted payload fragments from a larger example losing the outer comp-filter.
Related errors
- The {http://nextcloud.com/ns}comp-filter requires a valid na
- The {http://nextcloud.com/ns}limit has illegal value
- The {http://nextcloud.com/ns}offset has illegal value
- The {http://nextcloud.com/ns}param-filter requires a valid p
- The {http://nextcloud.com/ns}param-filter requires a valid p
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/78b0c1cd2614448c.
Report an issue: GitHub.