{"record":{"id":"5950fa6394e30d5c","repo":"phacility/phabricator","slug":"you-can-not-make-that-edit-because-it-would-remov","errorCode":null,"errorMessage":"You can not make that edit, because it would remove your ability to '%s' the object.","messagePattern":"You can not make that edit, because it would remove your ability to '(.+?)' the object\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/policy/filter/PhabricatorPolicyFilter.php","lineNumber":20,"sourceCode":"\nfinal class PhabricatorPolicyFilter extends Phobject {\n\n  private $viewer;\n  private $objects;\n  private $capabilities;\n  private $raisePolicyExceptions;\n  private $userProjects;\n  private $customPolicies = array();\n  private $objectPolicies = array();\n  private $forcedPolicy;\n\n  public static function mustRetainCapability(\n    PhabricatorUser $user,\n    PhabricatorPolicyInterface $object,\n    $capability) {\n\n    if (!self::hasCapability($user, $object, $capability)) {\n      throw new Exception(\n        pht(\n          \"You can not make that edit, because it would remove your ability \".\n          \"to '%s' the object.\",\n          $capability));\n    }\n  }\n\n  public static function requireCapability(\n    PhabricatorUser $user,\n    PhabricatorPolicyInterface $object,\n    $capability) {\n    $filter = id(new PhabricatorPolicyFilter())\n      ->setViewer($user)\n      ->requireCapabilities(array($capability))\n      ->raisePolicyExceptions(true)\n      ->apply(array($object));\n  }\n","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/policy/filter/PhabricatorPolicyFilter.php#L2-L38","documentation":"PhabricatorPolicyFilter::mustRetainCapability() is Phabricator's self-lockout guard. Before an edit that changes an object's policies is accepted, the actor is checked with hasCapability() on the object carrying the prospective new policy; if the check fails, the edit is refused. It exists so a user cannot push an object into a state they can no longer see or edit.","triggerScenarios":"Saving a policy transaction that switches view or edit to a custom rule or project policy that does not include the actor: for example setting a task's edit policy to a project you are not a member of, or a custom allow-list that omits your user PHID.","commonSituations":"Applying team-wide policy templates before joining the team, bulk policy edits run by scripts, and reassigning policies after an organizational restructuring.","solutions":["Satisfy the new policy first: join the target project or add your user PHID to the allow rule, then save.","Pick a destination policy that already includes you, such as a project you belong to.","If the edit genuinely must exclude you, have a user who satisfies the new policy perform it."],"exampleFix":"// before: custom rule allows only a project you are not in\n[{\"action\":\"allow\",\"rule\":\"PhabricatorProjectsPolicyRule\",\"value\":[\"PHID-PROJ-team\"]}]\n// after: also allow your own user PHID so you retain the capability\n[{\"action\":\"allow\",\"rule\":\"PhabricatorProjectsPolicyRule\",\"value\":[\"PHID-PROJ-team\"]},\n {\"action\":\"allow\",\"rule\":\"PhabricatorUsersPolicyRule\",\"value\":[\"PHID-USER-me\"]}]","handlingStrategy":"validation","validationCode":"// Before saving, confirm the new policy still grants you the capability.\n$still_ok = PhabricatorPolicyFilter::hasCapability(\n  $viewer,\n  $object_with_new_policy_applied,\n  PhabricatorPolicyCapability::CAN_EDIT);\nif (!$still_ok) {\n  // add yourself to the rule / join the project, or pick another policy\n}","typeGuard":null,"tryCatchPattern":"Catch Exception around the editor/save call and surface the capability name from the message; treat it as a hard stop — retrying the identical change will always fail.","preventionTips":["Join the destination project before switching a policy to it.","Keep your own user PHID in a custom allow rule until the edit is confirmed good.","In bulk policy scripts, compute whether the actor satisfies each target policy before applying."],"tags":["phabricator","policy","self-lockout","permissions","edit-policy"],"backgroundTag":"self-lockout-protection","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}