phacility/phabricator · warning · PhutilSearchQueryCompilerSyntaxException
Query has an invalid sequence of operators ("%s").
Error message
Query has an invalid sequence of operators ("%s"). What it means
While resolving a token's operator string (the sequence of +, -, and function prefixes like `title:` or `sub:`), the compiler hit a combination that has no defined meaning and fell into the default branch of the operator-resolution switch. Only well-formed combinations such as a single AND, NOT, SUBSTRING, or their negated/quoted variants are legal; anything else (e.g. `+-word`, `--word`, `+-sub:word`) is rejected with PhutilSearchQueryCompilerSyntaxException.
Source
Thrown at src/applications/search/compiler/PhutilSearchQueryCompiler.php:314
// search mode is normally useless.
if (phutil_utf8_is_cjk($value)) {
$use_substring = true;
} else if (phutil_preg_match('/^_/', $value)) {
// See T13632. Assume users searching for any term that begins
// with an undescore intend to perform substring search if they
// don't provide an explicit search function.
$use_substring = true;
}
}
if ($use_substring) {
$operator = self::OPERATOR_SUBSTRING;
} else {
$operator = self::OPERATOR_AND;
}
break;
default:
throw new PhutilSearchQueryCompilerSyntaxException(
pht(
'Query has an invalid sequence of operators ("%s").',
$operator_string));
}
if (!strlen($value)) {
$require_value = $is_quoted;
switch ($operator) {
case self::OPERATOR_NOT:
if ($enable_functions && ($token['function'] !== null)) {
$operator = self::OPERATOR_ABSENT;
$value = null;
} else {
$require_value = true;
}
break;
case self::OPERATOR_SUBSTRING:View on GitHub (pinned to 5720a38cfe)
Solutions
- Use exactly one leading operator per token: `-cat` (exclude) or `+cat`/`cat` (require) - never both.
- If building queries in code, collapse any operator stack to a single character before emitting: keep the last operator, drop the rest.
- For field functions use one function prefix per token (`title:cat`, `-title:cat`); combine field restrictions as separate tokens, not stacked prefixes.
- Re-enter the query manually in the UI; the offending operator string is printed in the exception message (`invalid sequence of operators ("+-")`).
Example fix
// before: concatenating flags can stack operators $prefix = ($exclude ? '-' : '').($require ? '+' : ''); $query = $prefix.$term; // after: at most one operator, exclusion wins $prefix = $exclude ? '-' : ($require ? '+' : ''); $query = $prefix.$term;
Defensive patterns
Strategy: validation
Validate before calling
// Collapse stacked operators before building queries $term = ltrim($term, '+-'); $term = $operator.$term; // $operator is '' , '+' or '-' only
Type guard
function hasValidOperatorSequence($q) { return !preg_match('/(^|\s)[+-]{2,}/', $q) && !preg_match('/(:){2,}/', $q); } Try / catch
try {
$result = $compiler->compileFunctionQuery($tokens);
} catch (PhutilSearchQueryCompilerSyntaxException $ex) {
return array('__invalid__' => $ex->getMessage()); // caller shows it inline
} Prevention
- Never concatenate optional operator prefixes
- Document the query mini-language where users type queries
- Fuzz-test query builders with random operators in unit tests (see PhutilSearchQueryCompilerTestCase)
When it happens
Trigger: Queries like `+-cat`, `-+cat`, `--cat`, `+-title:cat`, or stacking function prefixes `title:body:cat`; also operators glued together with no term between them (`a - + b` can collapse into a bogus operator sequence). Produced from the search box, saved queries, or Conduit search 'query' parameters.
Common situations: Users hand-editing saved queries and fat-fingering operator combos; scripts constructing queries by concatenating optional `-` prefixes (e.g. `($exclude ? '-' : '').($include ? '+' : '').$term` producing `+-term`); users trying to boost AND negate at once, which the language does not support.
Related errors
- Unknown search function "%s". Supported functions are: %s. (
- Query is too long (%s bytes, maximum is %s bytes).
- Query contains unmatched double quotes.
- Query contains a token ("%s") with no search term. Query tok
- Query field must be absent ("%s") and present ("%s"). This i
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/45e0e7468848fbe0.
Report an issue: GitHub.