{"record":{"id":"3c0c195cddc98d12","repo":"phacility/phabricator","slug":"the-underlying-file-does-not-exist-but-the-cached","errorCode":null,"errorMessage":"The underlying file does not exist, but the cached request was successful. This likely means the file record was manually deleted by an administrator.","messagePattern":"The underlying file does not exist, but the cached request was successful\\. This likely means the file record was manually deleted by an administrator\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/files/controller/PhabricatorFileImageProxyController.php","lineNumber":134,"sourceCode":"    return $this->getExternalResponse($external_request);\n  }\n\n  private function getExternalResponse(\n    PhabricatorFileExternalRequest $request) {\n    if (!$request->getIsSuccessful()) {\n      throw new Exception(\n        pht(\n          'Request to \"%s\" failed: %s',\n          $request->getURI(),\n          $request->getResponseMessage()));\n    }\n\n    $file = id(new PhabricatorFileQuery())\n      ->setViewer(PhabricatorUser::getOmnipotentUser())\n      ->withPHIDs(array($request->getFilePHID()))\n      ->executeOne();\n    if (!$file) {\n      throw new Exception(\n        pht(\n          'The underlying file does not exist, but the cached request was '.\n          'successful. This likely means the file record was manually '.\n          'deleted by an administrator.'));\n    }\n\n    return id(new AphrontAjaxResponse())\n      ->setContent(\n        array(\n          'imageURI' => $file->getViewURI(),\n        ));\n  }\n}\n","sourceCodeStart":116,"sourceCodeEnd":148,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/files/controller/PhabricatorFileImageProxyController.php#L116-L148","documentation":"Thrown when a cached PhabricatorFileExternalRequest was successful and points at a file PHID, but PhabricatorFileQuery (run as the omnipotent user) cannot load that file record. The proxy cache entry survived while the file row it references is gone, so the cached response can never be served. This is a data-consistency problem, almost always caused by deleting file rows without cleaning dependent records.","triggerScenarios":"An administrator deletes rows from the file table with raw SQL (or restores a partial dump) while file_externalrequest rows still reference the deleted PHID; the image proxy then hits the stale cache entry and fails to load the underlying file.","commonSituations":"Manual 'cleanup' of large files via SQL; restoring an old file table backup without file_externalrequest; destructive maintenance scripts that bypass PhabricatorDestructionEngine.","solutions":["Delete the stale file_externalrequest row(s) for that URI so the next request re-fetches the image fresh","Stop deleting file rows with SQL; destroy objects through Phabricator's destruction tooling (PhabricatorDestructionEngine), which removes dependent records","Sweep for other dangling references: compare file PHIDs in file_externalrequest against the file table and clean all stale rows in one pass"],"exampleFix":"-- before: raw SQL delete leaves a dangling proxy cache row\nDELETE FROM file WHERE phid = 'PHID-FILE-xxxx';\n\n-- after: destroy through the destruction tooling so dependents are cleaned,\n-- or remove the now-stale cache row explicitly\nDELETE FROM file_externalrequest WHERE filePHID = 'PHID-FILE-xxxx';","handlingStrategy":"fallback","validationCode":"$file = id(new PhabricatorFileQuery())\n  ->setViewer(PhabricatorUser::getOmnipotentUser())\n  ->withPHIDs(array($request->getFilePHID()))\n  ->executeOne();\nif (!$file) {\n  // cached entry is unusable: delete the stale request and re-fetch\n  $request->delete();\n}","typeGuard":null,"tryCatchPattern":"catch the Exception, delete the stale PhabricatorFileExternalRequest row, and re-fetch the image once instead of surfacing the inconsistency.","preventionTips":["Never delete file rows with raw SQL; use the destruction engine so dependent records are removed","Restore files_* tables together when recovering from backups"],"tags":["cache","data-consistency","manual-deletion","external-request"],"backgroundTag":"stale-cache-record","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}