phacility/phabricator · error · Exception
There are some results left in the result set.
Error message
There are some results left in the result set.
What it means
After processing the expected number of statements in a multi-query call, mysql_more_results() still reports pending result sets on the server side — the query string returned more results than the client consumed. The connection state is now inconsistent, so the driver aborts rather than silently dropping data. This is the ext-mysql driver's version of the check (mysqli has an identical one).
Source
Thrown at src/infrastructure/storage/connection/mysql/AphrontMySQLDatabaseConnection.php:137
}
if (!mysql_multi_query(implode("\n;\n\n", $raw_queries), $conn)) {
$ex = $this->processResult(false);
return array_fill_keys(array_keys($raw_queries), $ex);
}
$processed_all = false;
foreach ($raw_queries as $key => $raw_query) {
$results[$key] = $this->processResult(@mysql_fetch_result($conn));
if (!mysql_more_results($conn)) {
$processed_all = true;
break;
}
mysql_next_result($conn);
}
if (!$processed_all) {
throw new Exception(
pht('There are some results left in the result set.'));
}
return $results;
}
protected function freeResult($result) {
mysql_free_result($result);
}
public function supportsParallelQueries() {
// fb_parallel_query() doesn't support results with different columns.
return false;
}
/**
* @phutil-external-symbol function fb_parallel_query
*/View on GitHub (pinned to 5720a38cfe)
Solutions
- Execute one statement per query call: split scripts into individual queryfx() invocations
- If a stored procedure legitimately returns multiple sets, consume every set (loop while more_results) instead of expecting a fixed count
- Inspect the exact string being sent — look for stray semicolons or embedded statements from concatenation
- Prefer the mysqli driver path for new code; both enforce the same rule
Example fix
// before: multiple statements in one call queryfx($conn, 'UPDATE a SET x = 1; UPDATE b SET y = 2;'); // after: one statement per call queryfx($conn, 'UPDATE a SET x = 1'); queryfx($conn, 'UPDATE b SET y = 2');
Defensive patterns
Strategy: validation
Validate before calling
// Before executing, assert one statement per call:
function assert_single_statement($raw_query) {
if (preg_match('/;\s*\S/', trim($raw_query))) {
throw new Exception('Split multi-statement SQL into separate calls.');
}
return $raw_query;
} Prevention
- Send exactly one statement per queryf()/queryfx() call; split migration scripts programmatically
- Do not route stored procedures returning multiple sets through the fixed-count multi-query API
- Inspect concatenated SQL for stray semicolons before executing it
When it happens
Trigger: Passing several ';'-separated statements in a single queryf()/queryfx() call; calling a stored procedure that returns multiple result sets; a query string built by concatenation accidentally containing an extra statement or trailing semicolon fragment.
Common situations: Running hand-written migration SQL that was written as one script but executed as one query; wrapping procedural logic in stored procedures; copy-pasted dump fragments executed through the wrong API.
Related errors
- There are some results left in the result set.
- Configuration file specifies cluster peer ("%s", at index "%
- Expected `%s`!
- This repository ("%s") is not available over SSH.
- Client transmitted more than 1MB of data without transmittin
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/af88b1260fcc04e4.
Report an issue: GitHub.