{"record":{"id":"3bafc2beb8dc85b6","repo":"phacility/phabricator","slug":"failed-to-unserialize-xhprof-profile","errorCode":null,"errorMessage":"Failed to unserialize XHProf profile!","messagePattern":"Failed to unserialize XHProf profile!","errorType":"exception","errorClass":"PhutilProxyException","httpStatus":null,"severity":"error","filePath":"src/applications/xhprof/controller/PhabricatorXHProfProfileController.php","lineNumber":25,"sourceCode":"    return true;\n  }\n\n  public function handleRequest(AphrontRequest $request) {\n    $phid = $request->getURIData('phid');\n\n    $file = id(new PhabricatorFileQuery())\n      ->setViewer($request->getUser())\n      ->withPHIDs(array($phid))\n      ->executeOne();\n    if (!$file) {\n      return new Aphront404Response();\n    }\n\n    $data = $file->loadFileData();\n    try {\n      $data = phutil_json_decode($data);\n    } catch (PhutilJSONParserException $ex) {\n      throw new PhutilProxyException(\n        pht('Failed to unserialize XHProf profile!'),\n        $ex);\n    }\n\n    $symbol = $request->getStr('symbol');\n\n    $is_framed = $request->getBool('frame');\n\n    if ($symbol) {\n      $view = new PhabricatorXHProfProfileSymbolView();\n      $view->setSymbol($symbol);\n    } else {\n      $view = new PhabricatorXHProfProfileTopLevelView();\n      $view->setFile($file);\n      $view->setLimit(100);\n    }\n\n    $view->setBaseURI($request->getRequestURI()->getPath());","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/xhprof/controller/PhabricatorXHProfProfileController.php#L7-L43","documentation":"When rendering an XHProf profile page, Phabricator loads the stored profile file and decodes it with phutil_json_decode(). If the data is not valid JSON, the PhutilJSONParserException is re-thrown wrapped in this PhutilProxyException.","triggerScenarios":"Requesting /xhprof/profile/PHID-... for a file whose contents are corrupt: truncated upload, binary or PHP-serialized data from an external profiler instead of Phabricator's JSON sample format, or a file that was stored with the wrong content.","commonSituations":"Profiles pushed into Phabricator Files by scripts from a different XHProf capture pipeline; truncated multipart upload; very old or manually edited profile files; disk/storage corruption.","solutions":["Re-capture the profile with Phabricator's built-in XHProf sampling so the file is JSON in the expected shape.","Download the file and inspect it (file head) to confirm whether it is truncated or a foreign format.","Delete the corrupt profile file and regenerate it.","If serving profile pages programmatically, catch PhutilProxyException/PhutilJSONParserException and render a friendly error or 404 instead of a stack trace."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check profile data before handing it to the profile view\njson_decode($file_data, true);\nif (json_last_error() !== JSON_ERROR_NONE) {\n  // render a friendly 'corrupt profile' page or 404 instead of throwing\n}","typeGuard":null,"tryCatchPattern":"try {\n  $data = phutil_json_decode($file_data);\n} catch (PhutilJSONParserException $ex) {\n  throw new PhutilProxyException(\n    pht('Failed to unserialize XHProf profile!'),\n    $ex);\n}","preventionTips":["Only ingest profiles captured by Phabricator's own XHProf sampling pipeline (JSON format).","Verify file size/hash after upload to catch truncation.","Serve profile pages through a wrapper that converts decode failures into user-facing errors."],"tags":["phabricator","xhprof","profiling","json","data-corruption"],"backgroundTag":"json-parse-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}