{"record":{"id":"0d69018ddc458eea","repo":"nextcloud/server","slug":"the-given-request-is-not-valid","errorCode":null,"errorMessage":"The given request is not valid","messagePattern":"The given request is not valid","errorType":"exception","errorClass":"Sabre\\DAV\\Exception\\BadRequest","httpStatus":400,"severity":"error","filePath":"apps/dav/lib/DAV/Sharing/Plugin.php","lineNumber":178,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$node->updateShares($message->set, $message->remove);\n\n\t\t\t\t$response->setStatus(Http::STATUS_OK);\n\t\t\t\t// Adding this because sending a response body may cause issues,\n\t\t\t\t// and I wanted some type of indicator the response was handled.\n\t\t\t\t$response->setHeader('X-Sabre-Status', 'everything-went-well');\n\n\t\t\t\t// Breaking the event chain\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate function validateShareRequest($shareRequest): void {\n\t\tif (!$shareRequest instanceof ShareRequest) {\n\t\t\t// @FIXME: Replace switch-case in httpPost with instanceof ShareRequest\n\t\t\tthrow new BadRequest('The given request is not valid');\n\t\t}\n\n\t\t$elements = (count($shareRequest->set) + count($shareRequest->remove));\n\n\t\tif ($elements === 0) {\n\t\t\tthrow new BadRequest(ShareRequest::ELEMENT_SHARE . ' needs at least one set or remove element');\n\t\t}\n\n\t\tif ($elements > 10) {\n\t\t\tthrow new BadRequest(ShareRequest::ELEMENT_SHARE . ' is limited to 10 set or remove elements');\n\t\t}\n\t}\n\n\tprivate function preloadCollection(PropFind $propFind, ICollection $collection): void {\n\t\tif (!$collection instanceof CalendarHome || $propFind->getDepth() !== 1) {\n\t\t\treturn;\n\t\t}\n","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/DAV/Sharing/Plugin.php#L160-L196","documentation":"HTTP 400 BadRequest thrown by the DAV sharing plugin's validateShareRequest() when a POST body routed into the '{http://owncloud.org/ns}share' case does not deserialize into a ShareRequest object. The plugin registers the XML element map '{oc}share' -> ShareRequest and '{oc}invite' -> Invite, so this guard mostly fires defensively when the parsed root element maps to a different class than expected — malformed share XML or an elementMap overridden by another app.","triggerScenarios":"POST with Content-Type application/xml or text/xml to a calendar/address book path where the body parses to a message object that is not a ShareRequest — typically hand-built XML with the wrong root element/namespace, or another app overriding the server's xml elementMap for {oc}share.","commonSituations":"Custom provisioning tools generating share XML by string concatenation; clients migrating from the legacy {oc}invite protocol; typos in the http://owncloud.org/ns namespace URI; third-party DAV apps conflicting with the sharing plugin's element map.","solutions":["Send a well-formed share document: root element {http://owncloud.org/ns}share containing at least one set and/or remove child","Verify the namespace is exactly http://owncloud.org/ns and Content-Type is application/xml or text/xml","If you meant the legacy invite protocol, send an {http://owncloud.org/ns}invite document instead","Replay a known-good request (share via web UI while watching the DAV traffic) and diff it against your client's body"],"exampleFix":"// before: wrong root element/namespace -> 400 'The given request is not valid'\nPOST /remote.php/dav/addressbooks/admin/contacts/\nContent-Type: application/xml\n\n<x0:share xmlns:x0='http://calendarserver.org/ns/'>...</x0:share>\n// after\nPOST /remote.php/dav/addressbooks/admin/contacts/\nContent-Type: application/xml\n\n<x1:share xmlns:x1='http://owncloud.org/ns' xmlns:d='DAV:'>\n  <x1:set><d:href>principal:principals/users/alice</d:href></x1:set>\n</x1:share>","handlingStrategy":"validation","validationCode":"// validate before sending: root must be {http://owncloud.org/ns}share\nfunction assertShareDocument(xmlString) {\n  const doc = new DOMParser().parseFromString(xmlString, 'application/xml');\n  if (doc.querySelector('parsererror')) throw new Error('malformed XML');\n  const root = doc.documentElement;\n  if (root.namespaceURI !== 'http://owncloud.org/ns' || root.localName !== 'share') {\n    throw new Error('root element must be {http://owncloud.org/ns}share');\n  }\n  return doc;\n}","typeGuard":"function isShareRequestShape(parsed) {\n  return parsed !== null && typeof parsed === 'object'\n    && Array.isArray(parsed.set)\n    && Array.isArray(parsed.remove);\n}","tryCatchPattern":"try {\n  await davPost(bookUrl, shareBody);\n} catch (e) {\n  if (e.status === 400) { logClientError('share body rejected', shareBody); /* fix body, do not blind-retry */ }\n  else throw e;\n}","preventionTips":["Build share XML with a serializer, never string concatenation","Pin the namespace constant http://owncloud.org/ns in one place","Replay a known-good capture from the web UI when in doubt"],"tags":["dav","sharing","xml","bad-request","validation"],"backgroundTag":"invalid-request-body","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}