{"record":{"id":"e30e6e6643b34636","repo":"nextcloud/server","slug":"the-http-nextcloud-com-ns-filter-element-is-req","errorCode":null,"errorMessage":"The {http://nextcloud.com/ns}filter element is required for this request","messagePattern":"The (.+?)filter element is required for this request","errorType":"http","errorClass":"Sabre\\DAV\\Exception\\BadRequest","httpStatus":400,"severity":"error","filePath":"apps/dav/lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php","lineNumber":131,"sourceCode":"\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$newProps['filters']['params'][] = $subElem['value'];\n\t\t\t\t\t\t} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}search-term') {\n\t\t\t\t\t\t\t$newProps['filters']['search-term'] = $subElem['value'];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase '{' . SearchPlugin::NS_Nextcloud . '}limit':\n\t\t\t\t\t$newProps['limit'] = $elem['value'];\n\t\t\t\t\tbreak;\n\t\t\t\tcase '{' . SearchPlugin::NS_Nextcloud . '}offset':\n\t\t\t\t\t$newProps['offset'] = $elem['value'];\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\t\t}\n\n\t\tif (empty($newProps['filters'])) {\n\t\t\tthrow new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}filter element is required for this request');\n\t\t}\n\n\t\t$propsOrParamsDefined = (!empty($newProps['filters']['props']) || !empty($newProps['filters']['params']));\n\t\t$noCompsDefined = empty($newProps['filters']['comps']);\n\t\tif ($propsOrParamsDefined && $noCompsDefined) {\n\t\t\tthrow new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter given without any {' . SearchPlugin::NS_Nextcloud . '}comp-filter');\n\t\t}\n\n\t\tif (!isset($newProps['filters']['search-term'])) {\n\t\t\tthrow new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}search-term is required for this request');\n\t\t}\n\n\t\tif (empty($newProps['filters']['props']) && empty($newProps['filters']['params'])) {\n\t\t\tthrow new BadRequest('At least one{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter is required for this request');\n\t\t}\n\n\t\t$obj = new self();\n\t\tforeach ($newProps as $key => $value) {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php#L113-L149","documentation":"CalendarSearchReport::xmlDeserialize() collects the parsed children of the {http://nextcloud.com/ns}search-report payload and throws Sabre\\DAV\\Exception\\BadRequest (HTTP 400) when no {http://nextcloud.com/ns}filter element was among them. The filter block (with comps/props/params/search-term) is the mandatory core of the Nextcloud calendar search REPORT.","triggerScenarios":"Sending a search REPORT whose body has limit/offset (or nothing at all) but no <n:filter>...</n:filter> element.","commonSituations":"Clients treating filter as optional because other REPORT types allow empty bodies; partial JSON-to-XML conversion dropping the filter object; schema drift between client and server versions.","solutions":["Wrap the search criteria in a filter element: <n:filter>...</n:filter> containing comp-filter(s) and search-term","Reject empty search requests client-side before issuing the REPORT","Compare your payload with a working example captured from the Nextcloud web UI search"],"exampleFix":"// before\n<n:search-report xmlns:n=\"http://nextcloud.com/ns\"><n:limit>10</n:limit></n:search-report>\n\n// after\n<n:search-report xmlns:n=\"http://nextcloud.com/ns\">\n  <n:filter>\n    <n:comp-filter name=\"VEVENT\"/>\n    <n:prop-filter name=\"SUMMARY\"/>\n    <n:search-term>meeting</n:search-term>\n  </n:filter>\n  <n:limit>10</n:limit>\n</n:search-report>","handlingStrategy":"validation","validationCode":"function buildSearchReport(array $filters, string $term): string {\n    if ($filters === []) {\n        throw new InvalidArgumentException('n:filter with comps+props is required');\n    }\n    // ... emit <n:filter> wrapping comps, props and search-term\n}","typeGuard":"function hasFilterElement(string $xmlBody): bool {\n    return str_contains($xmlBody, '<n:filter');\n}","tryCatchPattern":"try {\n    $client->request('REPORT', $calendarUri, $xmlBody);\n} catch (\\Sabre\\Http\\ClientException $e) {\n    if ($e->getResponse()?->getStatus() === 400) { /* wrap criteria in <n:filter> */ }\n}","preventionTips":["Never submit the search REPORT without a filter block","Build payloads through a serializer with a required-field schema instead of string concatenation","Keep a golden-file test of a valid search-report body"],"tags":["caldav","xml","search","nextcloud","bad-request","report"],"backgroundTag":"webdav-400-bad-request","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}