phacility/phabricator · error · Exception

Capability "%s" has invalid policy "%s"; "%s" does not exist

Error message

Capability "%s" has invalid policy "%s"; "%s" does not exist.

What it means

Thrown by PhabricatorPolicyLockOptionType while validating the policy.lock configuration. Each capability in that map must point at a policy PHID that actually exists: every PHID is loaded through PhabricatorHandleQuery under the omnipotent user, and an incomplete handle means no object with that PHID exists, so the option value is rejected. It protects the install from locking applications to policies that can never be resolved.

Source

Thrown at src/applications/policy/config/PolicyLockOptionType.php:57

        if (!$capability->shouldAllowPublicPolicySetting()) {
          throw new Exception(
            pht(
              'Capability "%s" does not support public policy.',
              $capability_key));
        }
      }
    }

    if ($policy_phids) {
      $handles = id(new PhabricatorHandleQuery())
        ->setViewer(PhabricatorUser::getOmnipotentUser())
        ->withPhids($policy_phids)
        ->execute();
      $handles = mpull($handles, null, 'getPHID');
      foreach ($value as $capability_key => $policy) {
        $handle = $handles[$policy];
        if (!$handle->isComplete()) {
          throw new Exception(
            pht(
              'Capability "%s" has invalid policy "%s"; "%s" does not exist.',
              $capability_key,
              $policy,
              $policy));
        }
      }
    }
  }

}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Copy the policy PHID out of the message and verify it resolves: ./bin/phid lookup 'PHID-PROJ-...'
  2. If the referenced object is gone, create or pick an existing project, put its PHID into policy.lock, and save again.
  3. If locking is no longer wanted, clear the option: ./bin/config delete policy.lock

Example fix

// before: config points at a project that was deleted
{"view": "PHID-PROJ-4b2zdeadbeef"}
// after: PHID verified with ./bin/phid lookup, points at an existing project
{"view": "PHID-PROJ-7f3alive42"}
Defensive patterns

Strategy: validation

Validate before calling

// Before saving policy.lock, confirm every policy PHID resolves.
foreach (array_values($lock_map) as $phid) {
  $handle = id(new PhabricatorHandleQuery())
    ->setViewer(PhabricatorUser::getOmnipotentUser())
    ->withPHIDs(array($phid))
    ->executeOne();
  if (!$handle || !$handle->isComplete()) {
    throw new Exception(pht('Policy PHID %s does not resolve; refusing to save.', $phid));
  }
}
// CLI equivalent: ./bin/phid lookup PHID-PROJ-xxx

Prevention

When it happens

Trigger: Setting policy.lock so a capability (e.g. an application's view or edit capability) references a PHID that does not resolve: the project or object behind the PHID was deleted, the PHID contains a typo, or it was copied from a different Phabricator install.

Common situations: Copying policy.lock between staging and production, deleting or renaming projects that policies were locked to, and hand-editing the config value with a stale PHID from an earlier export.

Related errors


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