phacility/phabricator · error · Exception

You can not make that edit, because it would remove your abi

Error message

You can not make that edit, because it would remove your ability to '%s' the object.

What it means

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.

Source

Thrown at src/applications/policy/filter/PhabricatorPolicyFilter.php:20

final class PhabricatorPolicyFilter extends Phobject {

  private $viewer;
  private $objects;
  private $capabilities;
  private $raisePolicyExceptions;
  private $userProjects;
  private $customPolicies = array();
  private $objectPolicies = array();
  private $forcedPolicy;

  public static function mustRetainCapability(
    PhabricatorUser $user,
    PhabricatorPolicyInterface $object,
    $capability) {

    if (!self::hasCapability($user, $object, $capability)) {
      throw new Exception(
        pht(
          "You can not make that edit, because it would remove your ability ".
          "to '%s' the object.",
          $capability));
    }
  }

  public static function requireCapability(
    PhabricatorUser $user,
    PhabricatorPolicyInterface $object,
    $capability) {
    $filter = id(new PhabricatorPolicyFilter())
      ->setViewer($user)
      ->requireCapabilities(array($capability))
      ->raisePolicyExceptions(true)
      ->apply(array($object));
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Satisfy the new policy first: join the target project or add your user PHID to the allow rule, then save.
  2. Pick a destination policy that already includes you, such as a project you belong to.
  3. If the edit genuinely must exclude you, have a user who satisfies the new policy perform it.

Example fix

// before: custom rule allows only a project you are not in
[{"action":"allow","rule":"PhabricatorProjectsPolicyRule","value":["PHID-PROJ-team"]}]
// after: also allow your own user PHID so you retain the capability
[{"action":"allow","rule":"PhabricatorProjectsPolicyRule","value":["PHID-PROJ-team"]},
 {"action":"allow","rule":"PhabricatorUsersPolicyRule","value":["PHID-USER-me"]}]
Defensive patterns

Strategy: validation

Validate before calling

// Before saving, confirm the new policy still grants you the capability.
$still_ok = PhabricatorPolicyFilter::hasCapability(
  $viewer,
  $object_with_new_policy_applied,
  PhabricatorPolicyCapability::CAN_EDIT);
if (!$still_ok) {
  // add yourself to the rule / join the project, or pick another policy
}

Try / catch

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.

Prevention

When it happens

Trigger: 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.

Common situations: Applying team-wide policy templates before joining the team, bulk policy edits run by scripts, and reassigning policies after an organizational restructuring.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/5950fa6394e30d5c. Report an issue: GitHub.