{"record":{"id":"a409fc3a7931a811","repo":"phacility/phabricator","slug":"no-such-ast","errorCode":null,"errorMessage":"No such AST!","messagePattern":"No such AST!","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"src/applications/phpast/controller/PhabricatorXHPASTViewPanelController.php","lineNumber":19,"sourceCode":"<?php\n\nabstract class PhabricatorXHPASTViewPanelController\n  extends PhabricatorXHPASTViewController {\n\n  private $id;\n  private $storageTree;\n\n  public function shouldAllowPublic() {\n    return true;\n  }\n\n  public function willProcessRequest(array $data) {\n    $this->id = $data['id'];\n    $this->storageTree = id(new PhabricatorXHPASTParseTree())\n      ->load($this->id);\n\n    if (!$this->storageTree) {\n      throw new Exception(pht('No such AST!'));\n    }\n  }\n\n  protected function getStorageTree() {\n    return $this->storageTree;\n  }\n\n  protected function buildXHPASTViewPanelResponse($content) {\n    $content = hsprintf(\n      '<!DOCTYPE html>'.\n      '<html>'.\n        '<head>'.\n          '<style type=\"text/css\">\nbody {\n  white-space: pre;\n  font: 10px \"Monaco\";\n  cursor: pointer;\n}","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/phpast/controller/PhabricatorXHPASTViewPanelController.php#L1-L37","documentation":"The XHPAST demo panel (PhabricatorXHPASTViewPanelController) loads a stored PhabricatorXHPASTParseTree row by its raw numeric id during willProcessRequest(). 'No such AST!' is the not-found signal, thrown as a plain Exception before any rendering happens; it is effectively a 404. The panel allows public access, so anonymous visitors probing ids see it too.","triggerScenarios":"Visiting the XHPAST view panel with an id that has no phabricator_xhpast_parsetree row: a stale link to a garbage-collected tree, a database reset while old URLs persist, or a crawler probing sequential ids.","commonSituations":"Old bookmarks or pasted links to parsed AST dumps after the row was pruned; instance re-imports that dropped the xhpast tables; link scanners hitting the public panel.","solutions":["Regenerate the AST by submitting code through the XHPAST panel again and use the new id","Verify the row exists in phabricator_xhpast_parsetree if the id is believed valid","Treat it as a 404: no data is corrupted and no action is strictly required"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Resolve the tree before emitting or following a panel link.\n$tree = id(new PhabricatorXHPASTParseTree())->load($id);\nif (!$tree) {\n  return new Aphront404Response();\n}","typeGuard":"function xhpastTreeExists($id) {\n  return (bool)id(new PhabricatorXHPASTParseTree())->load($id);\n}","tryCatchPattern":"try {\n  $response = $this->handlePanelRequest($request);\n} catch (Exception $ex) {\n  if (strpos($ex->getMessage(), 'No such AST!') !== false) {\n    return new Aphront404Response();\n  }\n  throw $ex;\n}","preventionTips":["Treat missing parse-tree ids as 404s in any custom routing","Regenerate ASTs rather than persisting ids long-term","Do not publish deep links to demo panel output; trees are transient"],"tags":["phabricator","xhpast","php-ast","not-found","public-panel"],"backgroundTag":"entity-not-found-by-id","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}