{"record":{"id":"ca160b8cc182740f","repo":"phacility/phabricator","slug":"inline-comment-s-is-not-editable","errorCode":null,"errorMessage":"Inline comment \"%s\" is not editable.","messagePattern":"Inline comment \"(.+?)\" is not editable\\.","errorType":"http","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/infrastructure/diff/PhabricatorInlineCommentController.php","lineNumber":531,"sourceCode":"\n  final protected function loadCommentByIDForEdit($id) {\n    $viewer = $this->getViewer();\n\n    $query = $this->newInlineCommentQuery()\n      ->withIDs(array($id))\n      ->needInlineContext(true);\n\n    $inline = $this->loadCommentByQuery($query);\n\n    if (!$inline) {\n      throw new Exception(\n        pht(\n          'Unable to load inline \"%s\".',\n          $id));\n    }\n\n    if (!$this->canEditInlineComment($viewer, $inline)) {\n      throw new Exception(\n        pht(\n          'Inline comment \"%s\" is not editable.',\n          $id));\n    }\n\n    return $inline;\n  }\n\n  private function loadCommentByQuery(\n    PhabricatorDiffInlineCommentQuery $query) {\n    $viewer = $this->getViewer();\n\n    $inline = $query\n      ->setViewer($viewer)\n      ->executeOne();\n\n    if ($inline) {\n      $inline = $inline->newInlineCommentObject();","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/diff/PhabricatorInlineCommentController.php#L513-L549","documentation":"Thrown by loadCommentByIDForEdit() after the comment loaded successfully but canEditInlineComment($viewer, $inline) returned false. Each application controller implements the edit check; in practice only the comment's author (or users with edit rights over the container object) may edit an inline comment. The exception aborts the edit/preview request — this is a permissions failure on a comment that does exist.","triggerScenarios":"A non-author opening the edit endpoint for someone else's inline comment (e.g. `/differential/comment/inline/edit/{id}/` by URL manipulation); the author acting after the comment was reassigned or the viewer context changed; administrative scripts running as a viewer who is not the author.","commonSituations":"Users hand-editing URLs to modify others' review comments; automation replaying an edit request under a service account instead of the author; policy customization that narrows inline edit rights.","solutions":["Only edit comments authored by the acting user; ask the author to edit, or reply instead","If administrative editing is truly required, run as the author (e.g. via `bin/user` impersonation tooling) rather than rewriting policy","For custom integrations, check canEditInlineComment() logic in your subclass (DifferentialInlineCommentEditController::canEditInlineComment) if the rule is wrong for your install"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before rendering edit controls for an inline comment\n$can_edit = $viewer->getPHID() === $inline->getAuthorPHID();\nif (!$can_edit) {\n  // render read-only view / reply link instead of an edit action\n}","typeGuard":null,"tryCatchPattern":"try {\n  $inline = $this->loadCommentByIDForEdit($id);\n} catch (Exception $ex) {\n  // covers both 'not loadable' and 'not editable': respond 403/404\n  return new Aphront403Response();\n}","preventionTips":["Gate edit actions in the UI on authorship so users never reach the endpoint","In API/automation, authenticate as the comment's author when edits are required"],"tags":["phabricator","inline-comments","code-review","permission-denied","edit"],"backgroundTag":"permission-denied","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}