nextcloud/server · error · Sabre\DAV\Exception\BadRequest

At least one{http://nextcloud.com/ns}prop-filter or {http://

Error message

At least one{http://nextcloud.com/ns}prop-filter or {http://nextcloud.com/ns}param-filter is required for this request

What it means

Final structural check in CalendarSearchReport::xmlDeserialize(): the filter carries a search-term (and maybe comp-filters) but neither prop-filters nor param-filters, so there is no property to run the substring search against and the server throws Sabre\DAV\Exception\BadRequest (HTTP 400). At least one prop-filter or param-filter must restrict which property is searched.

Source

Thrown at apps/dav/lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php:145

			}
		}

		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

  1. Add at least one prop-filter, commonly <n:prop-filter name="SUMMARY"/>
  2. Expose multiple prop-filters (SUMMARY, DESCRIPTION, LOCATION, ATTENDEE) in the UI if users expect broad search
  3. Client-side, validate that count(props)+count(params) >= 1 before sending

Example fix

// before
<n:filter>
  <n:comp-filter name="VEVENT"/>
  <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

if ($props === [] && $params === []) {
    $props = ['SUMMARY']; // search-report requires at least one prop- or param-filter
}

Type guard

function hasAtLeastOnePropOrParamFilter(array $props, array $params): bool {
    return $props !== [] || $params !== [];
}

Try / catch

try {
    $client->request('REPORT', $calendarUri, $xmlBody);
} catch (\Sabre\Http\ClientException $e) {
    if ($e->getResponse()?->getStatus() === 400) { /* add <n:prop-filter name="SUMMARY"/> */ }
}

Prevention

When it happens

Trigger: Sending <n:filter><n:comp-filter name="VEVENT"/><n:search-term>x</n:search-term></n:filter> with no <n:prop-filter> or <n:param-filter>.

Common situations: Users expecting a global full-text search over all fields; search UIs that make the property picker optional; payloads trimmed down during debugging.

Related errors


AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17). Data as JSON: /api/errors/73c722282cde0432. Report an issue: GitHub.