phacility/phabricator · warning · PhutilSearchQueryCompilerSyntaxException
Query contains unmatched double quotes.
Error message
Query contains unmatched double quotes.
What it means
The search query tokenizer finished scanning the whole input while still inside a double-quoted string ($is_quoted stayed true). Phabricator's query language uses quotes for exact/substring phrases (e.g. `"walk the dog"`, or quoting a term that contains an operator character like `"cat:dog"`), and an opening quote with no closing quote leaves the parser dangling, so it throws PhutilSearchQueryCompilerSyntaxException before compiling.
Source
Thrown at src/applications/search/compiler/PhutilSearchQueryCompiler.php:248
if ($enable_functions) {
$token['function'] = $current_function;
}
$tokens[] = $token;
$current_operator = array();
$current_token = array();
$current_function = null;
continue;
} else {
$current_token[] = $character;
}
}
}
if ($is_quoted) {
throw new PhutilSearchQueryCompilerSyntaxException(
pht(
'Query contains unmatched double quotes.'));
}
// If the input query has trailing space, like "a b ", we may exit the
// parser without a final token.
if ($current_function !== null || $current_operator || $current_token) {
$token = array(
'operator' => $current_operator,
'quoted' => false,
'value' => $current_token,
);
if ($enable_functions) {
$token['function'] = $current_function;
}
$tokens[] = $token;View on GitHub (pinned to 5720a38cfe)
Solutions
- Count the double quotes in the query and add the missing closing quote: `fix "typo"`.
- If the quote is intentional content (apostrophe/quote inside a word), remove it or quote the whole term so quotes pair up.
- For programmatic callers, escape or strip double quotes from user-supplied fragments before embedding them: str_replace('"', '', $fragment) or wrap the whole fragment in one pair of quotes.
- Surface this exception to the user as a validation error (it is PhutilSearchQueryCompilerSyntaxException, designed to be user-facing) rather than logging it as a server fault.
Example fix
// before: unbalanced quotes in the query string
$query = 'fix "typo';
// after
$query = 'fix "typo"';
// or programmatically balance/strip
$frag = str_replace('"', '', $user_input);
$query = "fix \"{$frag}\""; Defensive patterns
Strategy: validation
Validate before calling
// Cheap parity check before submit/compile
if (substr_count($query, '"') % 2 !== 0) {
$errors[] = pht('Query contains an unmatched double quote.');
} Type guard
function hasBalancedQuotes($q) { return substr_count($q, '"') % 2 === 0; } Try / catch
try {
$tokens = $compiler->tokenizeQuery($query);
} catch (PhutilSearchQueryCompilerSyntaxException $ex) {
$view->setErrors(array($ex->getMessage())); // render back into the form
} Prevention
- Client-side: validate quote parity in the search box before POST
- Quote-programmatically: wrap any fragment containing special characters as a whole quoted phrase
- Treat PhutilSearchQueryCompilerSyntaxException as validation, never as a 500
When it happens
Trigger: A query like `fix "typo` (missing closing quote), `"unclosed`, or text where a quote is used as an apostrophe: `don't"t` style input, or a term containing a colon quoted only on one side (`cat:"dog`). Typing in the global search box or any application search field, or sending such a string through Conduit search parameters.
Common situations: Users pasting prose that contains one double quote (e.g. quoted error messages); smart quotes converted to straight quotes on one side only; programmatic callers building queries by concatenating fragments without escaping quotes; a term with a colon partially quoted per the 'surround in double quotes' advice but with one quote forgotten.
Related errors
- Query contains a token ("%s") with no search term. Query tok
- Query is too long (%s bytes, maximum is %s bytes).
- Query has an invalid sequence of operators ("%s").
- Constraint "%s" is not a valid constraint for this query.
- Minimum page size for API searches is 1, but this call speci
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/a1df063b4fe52c66.
Report an issue: GitHub.