{"record":{"id":"a1f88a1618cf130f","repo":"nextcloud/server","slug":"the-http-nextcloud-com-ns-param-filter-requires-a1f88a","errorCode":null,"errorMessage":"The {http://nextcloud.com/ns}param-filter requires a valid parameter attribute","messagePattern":"The (.+?)param-filter requires a valid parameter attribute","errorType":"http","errorClass":"Sabre\\DAV\\Exception\\BadRequest","httpStatus":400,"severity":"error","filePath":"apps/dav/lib/CalDAV/Search/Xml/Filter/ParamFilter.php","lineNumber":36,"sourceCode":"\n\t/**\n\t * @param Reader $reader\n\t * @throws BadRequest\n\t * @return string\n\t */\n\t#[\\Override]\n\tpublic static function xmlDeserialize(Reader $reader) {\n\t\t$att = $reader->parseAttributes();\n\t\t$property = $att['property'];\n\t\t$parameter = $att['name'];\n\n\t\t$reader->parseInnerTree();\n\n\t\tif (!is_string($property)) {\n\t\t\tthrow new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute');\n\t\t}\n\t\tif (!is_string($parameter)) {\n\t\t\tthrow new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute');\n\t\t}\n\n\t\treturn [\n\t\t\t'property' => $property,\n\t\t\t'parameter' => $parameter,\n\t\t];\n\t}\n}\n","sourceCodeStart":18,"sourceCodeEnd":45,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/CalDAV/Search/Xml/Filter/ParamFilter.php#L18-L45","documentation":"Second attribute check in ParamFilter::xmlDeserialize(): the {http://nextcloud.com/ns}param-filter element lacks a valid name attribute (the parameter name to match, e.g. PARTSTAT or CN), so $att['name'] is not a string and a Sabre\\DAV\\Exception\\BadRequest (HTTP 400) is thrown for the search REPORT.","triggerScenarios":"Sending <n:param-filter property=\"ATTENDEE\"/> with no name attribute.","commonSituations":"Client forms that build param filters from optional inputs and skip empty names but still emit the element; typos like param= instead of name=.","solutions":["Add the parameter name: <n:param-filter property=\"ATTENDEE\" name=\"PARTSTAT\"/>","Skip emitting the param-filter element when no parameter name is selected","Assert both attributes are non-empty strings in the code that builds the XML"],"exampleFix":"// before\n<n:param-filter property=\"ATTENDEE\"/>\n\n// after\n<n:param-filter property=\"ATTENDEE\" name=\"PARTSTAT\"/>","handlingStrategy":"validation","validationCode":"if (!is_string($paramName) || $paramName === '') {\n    // skip the param-filter instead of sending an invalid one\n    return '';\n}\n$xml = \"<n:param-filter property=\\\"{$property}\\\" name=\\\"{$paramName}\\\"/>\";","typeGuard":"function isValidParamName(mixed $name): bool {\n    return is_string($name) && $name !== ''\n        && preg_match('/^[A-Z0-9-]+$/', $name) === 1;\n}","tryCatchPattern":"try {\n    $client->request('REPORT', $calendarUri, $xmlBody);\n} catch (\\Sabre\\Http\\ClientException $e) {\n    if ($e->getResponse()?->getStatus() === 400) { /* add name=\"...\" to param-filter */ }\n}","preventionTips":["Map optional UI inputs to conditional element emission, not empty attributes","Use the attribute name= for the parameter (not param=)","Assert both attributes present in payload unit tests"],"tags":["caldav","xml","search","nextcloud","bad-request","param-filter"],"backgroundTag":"webdav-400-bad-request","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}