phacility/phabricator · warning · PhutilSearchQueryCompilerSyntaxException
Query field must be absent ("%s") and present ("%s"). This i
Error message
Query field must be absent ("%s") and present ("%s"). This is impossible, so the query is not valid. What it means
Post-parse validation in PhutilSearchQueryCompiler: after grouping tokens by search function (field), it found at least one field that is simultaneously required to be ABSENT (via empty-value function tokens like `-field:""`) and PRESENT (via `+field:""` style or any present-empty token on the same field). Both constraints can never be satisfied together, so the query is rejected as impossible rather than compiled into SQL that returns nothing.
Source
Thrown at src/applications/search/compiler/PhutilSearchQueryCompiler.php:427
$function = $result['function'];
if ($result['operator'] === self::OPERATOR_ABSENT) {
$absent_tokens[$function][] = $result;
} else {
$present_tokens[$function][] = $result;
}
}
foreach ($absent_tokens as $function => $tokens) {
$absent_token = head($tokens);
if (empty($present_tokens[$function])) {
continue;
}
$present_token = head($present_tokens[$function]);
throw new PhutilSearchQueryCompilerSyntaxException(
pht(
'Query field must be absent ("%s") and present ("%s"). This '.
'is impossible, so the query is not valid.',
$absent_token['raw'],
$present_token['raw']));
}
}
return $results;
}
private function renderToken(
PhutilSearchQueryToken $token,
PhutilSearchStemmer $stemmer = null) {
$value = $token->getValue();
if ($stemmer) {
$value = $stemmer->stemToken($value);View on GitHub (pinned to 5720a38cfe)
Solutions
- Pick one polarity per field: keep either `field:""` (must have a value) or `-field:""` (must not), never both.
- In UI: reopen the query edit form, find the field constrained twice in opposite ways, and clear one of the two checkboxes.
- In code: before concatenating per-user filters into one query, track chosen polarity per function key and drop the opposite constraint with a warning.
- If you genuinely need 'field empty OR non-empty', that is everything - just remove both tokens.
Example fix
// before: contradictory presence/absence on the same field $query = 'title:"" -title:"" grass'; // after: choose one polarity $query = '-title:"" grass'; // only documents with no title
Defensive patterns
Strategy: validation
Validate before calling
// Before merging user filters into one query string, enforce one polarity per field
foreach ($requested_functions as $fn) {
if (isset($seen[$fn]) && $seen[$fn] !== $polarity) {
unset($filters[$fn]); // drop contradiction, warn the user
}
$seen[$fn] = $polarity;
} Type guard
function hasNoContradictoryFields(array $tokens) { $p = array(); foreach ($tokens as $t) { $f = $t['function']; if ($f === null) continue; $pol = $t['operator'] === 'NOT' ? '-' : '+'; if (isset($p[$f]) && $p[$f] !== $pol) return false; $p[$f] = $pol; } return true; } Try / catch
try {
$results = $engine->buildQueryFromTokens($tokens);
} catch (PhutilSearchQueryCompilerSyntaxException $ex) {
$dialog->appendParagraph($ex->getMessage()); // explain the contradiction
} Prevention
- In custom query UIs, make presence/absence for a field a single tri-state control, not two checkboxes
- When merging saved queries, deduplicate per-field constraints explicitly
- Unit-test merge helpers with same-field-opposite-polarity cases
When it happens
Trigger: Queries mixing presence and absence on the same field, e.g. `title:"" -title:""`, `+projects:"" -projects:""`, or combining two saved-query fragments that each constrain the same field in opposite directions. Any Ferret-backed application search (Maniphest, Differential, Users, global search) with function tokens on the same field in both polarities.
Common situations: Users OR-ing/merging advanced query forms where 'has any value' and 'has no value' boxes for the same field are both checked; programmatic query builders that concatenate user filters without deduplicating per-field polarity; migrated saved queries that accumulated contradictory filters over time.
Related errors
- Query is too long (%s bytes, maximum is %s bytes).
- Query has an invalid sequence of operators ("%s").
- Unknown search function "%s". Supported functions are: %s. (
- To search for commits which are ancestors of particular refs
- Subversion does not support searching for ancestors of a par
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/bc4b717d0c6fd59c.
Report an issue: GitHub.