{"record":{"id":"0f0981c2e9018248","repo":"phacility/phabricator","slug":"query-of-class-s-overheated-examined-more-th","errorCode":null,"errorMessage":"Query (of class \"%s\") overheated: examined more than %s raw rows without finding %s visible objects.","messagePattern":"Query \\(of class \"(.+?)\"\\) overheated: examined more than (.+?) raw rows without finding (.+?) visible objects\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php","lineNumber":342,"sourceCode":"      if (!$this->rawResultLimit) {\n        // If we don't have a load count, we loaded all the results. We do\n        // not need to load another page.\n        break;\n      }\n\n      if (count($page) < $this->rawResultLimit) {\n        // If we have a load count but the unfiltered results contained fewer\n        // objects, we know this was the last page of objects; we do not need\n        // to load another page because we can deduce it would be empty.\n        break;\n      }\n\n      if (!$this->disableOverheating) {\n        if ($overheat_limit && ($total_seen >= $overheat_limit)) {\n          $this->isOverheated = true;\n\n          if (!$this->returnPartialResultsOnOverheat) {\n            throw new Exception(\n              pht(\n                'Query (of class \"%s\") overheated: examined more than %s '.\n                'raw rows without finding %s visible objects.',\n                get_class($this),\n                new PhutilNumber($overheat_limit),\n                new PhutilNumber($need)));\n          }\n\n          break;\n        }\n      }\n    } while (true);\n\n    $results = $this->didLoadResults($results);\n\n    return $results;\n  }\n","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php#L324-L360","documentation":"Thrown by PhabricatorPolicyAwareQuery when a policy-filtered query has examined more raw rows than its overheat budget — computed as the number of results still needed times 10 — without accumulating enough policy-visible objects. Phabricator pages through raw database rows and filters by policy in the application; without a cap, a viewer who can see almost nothing would force a full table scan. Overheating aborts the query to protect the database; setReturnPartialResultsOnOverheat() or setDisableOverheating() change that behavior, and getIsOverheated() reports it afterwards.","triggerScenarios":"A viewer whose policies exclude nearly all objects running a broad query (large 'all' queries as a restricted user); queries whose WHERE clause matches many rows but whose policy filtering discards most of them; setting a very small result limit while raw matches are huge.","commonSituations":"New restricted/bot accounts listing large object collections; mail/notification generation as a restricted daemon user; dashboards running aggregate queries for low-privilege viewers.","solutions":["Narrow the query with real constraints (withStatuses, withDateCreated, projects, etc.) so the database returns fewer raw rows","If partial results are acceptable, call setReturnPartialResultsOnOverheat(true) and check getIsOverheated() to warn the user","For trusted internal batch work (exports, daemons), call setDisableOverheating(true) — only where you are certain the row volume is bounded","Review the viewer's policy configuration: if they should see these objects, fix the policy so rows are not discarded after fetching"],"exampleFix":"// before\n$results = $query->setViewer($user)->execute();\n\n// after: accept partial results and surface that fact\n$results = id(clone $query)\n  ->setViewer($user)\n  ->setReturnPartialResultsOnOverheat(true)\n  ->execute();\nif ($query->getIsOverheated()) {\n  // tell the user results are truncated; suggest narrower filters\n}","handlingStrategy":"fallback","validationCode":"// If you cannot afford partial results, bound the query instead:\n// add real constraints so raw rows are unlikely to hit 10x the limit.\n$query->withDateCreatedBetween($start, $end); // etc.\n// Optionally pre-flight with a tiny limit to estimate selectivity:\n$probe = id(clone $query)->setLimit(1)->execute();","typeGuard":null,"tryCatchPattern":"try {\n  $results = $query->execute();\n} catch (Exception $ex) {\n  if (preg_match('/overheated/', $ex->getMessage())) {\n    // fall back: accept truncated results and flag them to the user\n    $results = id(clone $query)\n      ->setReturnPartialResultsOnOverheat(true)\n      ->execute();\n    // $query->getIsOverheated() === true here\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["For untrusted/broad viewers, always add selective constraints instead of listing everything","Use setReturnPartialResultsOnOverheat(true) plus getIsOverheated() for user-facing search pages","Reserve setDisableOverheating(true) for trusted, bounded batch jobs"],"tags":["query","policy","performance","resource-limit","phabricator"],"backgroundTag":"query-resource-limit","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}