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

The {http://nextcloud.com/ns}search-term has illegal value

Error message

The {http://nextcloud.com/ns}search-term has illegal value

What it means

Thrown while deserializing {http://nextcloud.com/ns}search-term: SearchTermFilter::xmlDeserialize() requires parseInnerTree() to return a string, and anything else (null from an empty element, or nested XML) triggers Sabre\DAV\Exception\BadRequest (HTTP 400). The element's text content is the substring the server searches for in the filtered properties.

Source

Thrown at apps/dav/lib/CalDAV/Search/Xml/Filter/SearchTermFilter.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 SearchTermFilter implements XmlDeserializable {

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

		return $value;
	}
}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Ensure the element contains the query text: <n:search-term>team meeting</n:search-term>
  2. Do not submit the REPORT at all when the user entered no search term
  3. Give the value a default (e.g. empty means match-all is not supported; require >= 1 char)

Example fix

// before
<n:search-term/>

// after
<n:search-term>team meeting</n:search-term>
Defensive patterns

Strategy: validation

Validate before calling

if (!is_string($term) || trim($term) === '') {
    // do not send the REPORT without a search term
    return [];
}
$xml = '<n:search-term>' . htmlspecialchars($term, ENT_XML1) . '</n:search-term>';

Type guard

function isValidSearchTerm(mixed $term): bool {
    return is_string($term) && trim($term) !== '';
}

Try / catch

try {
    $client->request('REPORT', $calendarUri, $xmlBody);
} catch (\Sabre\Http\ClientException $e) {
    if ($e->getResponse()?->getStatus() === 400) { /* empty search-term: require input */ }
}

Prevention

When it happens

Trigger: Sending <n:search-term/> with no text, or putting child elements inside it instead of the search text.

Common situations: Search UIs submitting an empty query box; empty-string values dropped by an XML writer; whitespace-only content trimmed to null by the parser.

Related errors


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