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

The {http://nextcloud.com/ns}limit has illegal value

Error message

The {http://nextcloud.com/ns}limit has illegal value

What it means

Thrown when deserializing the {http://nextcloud.com/ns}limit element of a Nextcloud CalDAV search REPORT: parseInnerTree() returned something that is neither int nor string (typically null for an empty element), so LimitFilter::xmlDeserialize() raises Sabre\DAV\Exception\BadRequest (HTTP 400). The element must contain a numeric text value.

Source

Thrown at apps/dav/lib/CalDAV/Search/Xml/Filter/LimitFilter.php:28

namespace OCA\DAV\CalDAV\Search\Xml\Filter;

use OCA\DAV\CalDAV\Search\SearchPlugin;
use Sabre\DAV\Exception\BadRequest;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;

class LimitFilter implements XmlDeserializable {

	/**
	 * @param Reader $reader
	 * @throws BadRequest
	 * @return int
	 */
	#[\Override]
	public static function xmlDeserialize(Reader $reader) {
		$value = $reader->parseInnerTree();
		if (!is_int($value) && !is_string($value)) {
			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}limit has illegal value');
		}

		return (int)$value;
	}
}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Omit the <n:limit> element entirely when you do not want pagination
  2. Otherwise give it text content: <n:limit>50</n:limit>
  3. Check your serializer is not dropping scalar text content of empty-valued fields

Example fix

// before
<n:limit/>

// after
<n:limit>50</n:limit>
Defensive patterns

Strategy: validation

Validate before calling

$xml = '';
if ($limit !== null) {
    $xml .= '<n:limit>' . (int) $limit . '</n:limit>'; // omit entirely when unset
}

Type guard

function isValidLimit(mixed $limit): bool {
    return $limit === null || (is_int($limit) && $limit > 0);
}

Try / catch

try {
    $client->request('REPORT', $calendarUri, $xmlBody);
} catch (\Sabre\Http\ClientException $e) {
    if ($e->getResponse()?->getStatus() === 400) { /* empty <n:limit/>: send text or drop element */ }
}

Prevention

When it happens

Trigger: Sending <n:limit/> (self-closing, empty) or one whose content deserializes to a non-scalar, e.g. nested child elements instead of text.

Common situations: Client code that always emits limit/offset tags but leaves them empty when no pagination is set; templates copied from another namespace where the element is a no-op.

Related errors


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