{"record":{"id":"3fbc15304d91c9d7","repo":"phacility/phabricator","slug":"d-s","errorCode":null,"errorMessage":"#%d: %s","messagePattern":"#%d: %s","errorType":"exception","errorClass":"AphrontConnectionLostQueryException","httpStatus":null,"severity":"error","filePath":"src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php","lineNumber":329,"sourceCode":"\n  protected function throwQueryException($connection) {\n    if ($this->nextError) {\n      $errno = $this->nextError;\n      $error = pht('Simulated error.');\n      $this->nextError = null;\n    } else {\n      $errno = $this->getErrorCode($connection);\n      $error = $this->getErrorDescription($connection);\n    }\n    $this->throwQueryCodeException($errno, $error);\n  }\n\n  private function throwCommonException($errno, $error) {\n    $message = pht('#%d: %s', $errno, $error);\n\n    switch ($errno) {\n      case 2013: // Connection Dropped\n        throw new AphrontConnectionLostQueryException($message);\n      case 2006: // Gone Away\n        $more = pht(\n          'This error may occur if your configured MySQL \"wait_timeout\" or '.\n          '\"max_allowed_packet\" values are too small. This may also indicate '.\n          'that something used the MySQL \"KILL <process>\" command to kill '.\n          'the connection running the query.');\n        throw new AphrontConnectionLostQueryException(\"{$message}\\n\\n{$more}\");\n      case 1213: // Deadlock\n        throw new AphrontDeadlockQueryException($message);\n      case 1205: // Lock wait timeout exceeded\n        throw new AphrontLockTimeoutQueryException($message);\n      case 1062: // Duplicate Key\n        // NOTE: In some versions of MySQL we get a key name back here, but\n        // older versions just give us a key index (\"key 2\") so it's not\n        // portable to parse the key out of the error and attach it to the\n        // exception.\n        throw new AphrontDuplicateKeyQueryException($message);\n      case 1044: // Access denied to database","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php#L311-L347","documentation":"The common wrapper Phabricator's MySQL connection layer uses to surface raw MySQL errors: the server/client error number and description are formatted as '#<errno>: <description>' and then mapped in throwCommonException() to typed query exceptions — e.g. errno 2013 (connection dropped) becomes AphrontConnectionLostQueryException. Seeing this shape means a MySQL-level failure was translated; the typed exception class and errno carry the actual diagnosis. Phabricator's workers automatically retry queries that failed with transient (connection/deadlock) exceptions.","triggerScenarios":"Any MySQL statement failure while the connection is severed (packet loss, restart of mysqld, proxy idle timeout) — errno 2013 'Lost connection to MySQL server during query'; also the shared prefix of the 2006/1213/1205/1062/1142 mappings emitted from the same switch.","commonSituations":"Long-running daemons holding idle connections cut by a firewall or load balancer; mysqld restarting under the application; network blips between web hosts and the database.","solutions":["Identify the errno in the '#<errno>:' prefix and follow its specific remedy (2006/2013: connection; 1213: deadlock; 1205: lock timeout)","If you are executing queries yourself, retry on AphrontConnectionLostQueryException with a fresh connection — the daemons already do this","Check mysqld uptime/logs to see whether the server restarted at that moment","For frequent idle drops, lower wait_timeout-side keepalives or enable TCP keepalives between hosts"],"exampleFix":"// before: assuming a query always succeeds\n$rows = queryfx_all($conn, 'SELECT * FROM %T', $table);\n\n// after: retry transient connection losses with a new connection\nfor ($attempt = 0; $attempt < 3; $attempt++) {\n  try {\n    $rows = queryfx_all($conn, 'SELECT * FROM %T', $table);\n    break;\n  } catch (AphrontConnectionLostQueryException $ex) {\n    $conn = $object->establishConnection('r'); // fresh connection\n  }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  $rows = queryfx_all($conn, $sql);\n} catch (AphrontConnectionLostQueryException $ex) {\n  // transient: re-establish and retry (Phabricator workers do this for you)\n  $conn = $object->establishConnection($mode);\n  $rows = queryfx_all($conn, $sql);\n}","preventionTips":["Parse the '#<errno>:' prefix to route to the right remedy (connection, deadlock, lock timeout, duplicate key)","Do not cache database connections across long idle periods in daemons; reopen before use","Monitor mysqld restarts and network stability when these appear in bursts"],"tags":["database","mysql","connection-lost","phabricator"],"backgroundTag":"mysql-connection-lost","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}