{"record":{"id":"bc4b717d0c6fd59c","repo":"phacility/phabricator","slug":"query-field-must-be-absent-s-and-present-s","errorCode":null,"errorMessage":"Query field must be absent (\"%s\") and present (\"%s\"). This is impossible, so the query is not valid.","messagePattern":"Query field must be absent \\(\"(.+?)\"\\) and present \\(\"(.+?)\"\\)\\. This is impossible, so the query is not valid\\.","errorType":"validation","errorClass":"PhutilSearchQueryCompilerSyntaxException","httpStatus":null,"severity":"warning","filePath":"src/applications/search/compiler/PhutilSearchQueryCompiler.php","lineNumber":427,"sourceCode":"        $function = $result['function'];\n\n        if ($result['operator'] === self::OPERATOR_ABSENT) {\n          $absent_tokens[$function][] = $result;\n        } else {\n          $present_tokens[$function][] = $result;\n        }\n      }\n\n      foreach ($absent_tokens as $function => $tokens) {\n        $absent_token = head($tokens);\n\n        if (empty($present_tokens[$function])) {\n          continue;\n        }\n\n        $present_token = head($present_tokens[$function]);\n\n        throw new PhutilSearchQueryCompilerSyntaxException(\n          pht(\n            'Query field must be absent (\"%s\") and present (\"%s\"). This '.\n            'is impossible, so the query is not valid.',\n            $absent_token['raw'],\n            $present_token['raw']));\n      }\n    }\n\n    return $results;\n  }\n\n  private function renderToken(\n    PhutilSearchQueryToken $token,\n    PhutilSearchStemmer $stemmer = null) {\n    $value = $token->getValue();\n\n    if ($stemmer) {\n      $value = $stemmer->stemToken($value);","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/search/compiler/PhutilSearchQueryCompiler.php#L409-L445","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: contradictory presence/absence on the same field\n$query = 'title:\"\" -title:\"\" grass';\n\n// after: choose one polarity\n$query = '-title:\"\" grass'; // only documents with no title","handlingStrategy":"validation","validationCode":"// Before merging user filters into one query string, enforce one polarity per field\nforeach ($requested_functions as $fn) {\n  if (isset($seen[$fn]) && $seen[$fn] !== $polarity) {\n    unset($filters[$fn]); // drop contradiction, warn the user\n  }\n  $seen[$fn] = $polarity;\n}","typeGuard":"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; }","tryCatchPattern":"try {\n  $results = $engine->buildQueryFromTokens($tokens);\n} catch (PhutilSearchQueryCompilerSyntaxException $ex) {\n  $dialog->appendParagraph($ex->getMessage()); // explain the contradiction\n}","preventionTips":["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"],"tags":["phabricator","search","query-semantics","contradictory-constraints","ferret"],"backgroundTag":"contradictory-query-constraints","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}