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

  1. Use exactly one leading operator per token: `-cat` (exclude) or `+cat`/`cat` (require) - never both.
  2. If building queries in code, collapse any operator stack to a single character before emitting: keep the last operator, drop the rest.
  3. For field functions use one function prefix per token (`title:cat`, `-title:cat`); combine field restrictions as separate tokens, not stacked prefixes.
  4. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/45e0e7468848fbe0. Report an issue: GitHub.