phacility/phabricator · error · Exception
Capability "%s" has invalid policy "%s".
Error message
Capability "%s" has invalid policy "%s".
What it means
Each value in policy.lock must be either a concrete object PHID (phid_get_type recognizes it) or a global policy constant that PhabricatorPolicyQuery::getGlobalPolicy() accepts, such as 'public', 'users', 'admin' or 'no-one'. Anything else fails validation, and the catch block around getGlobalPolicy() rethrows with this clearer message naming the capability and the invalid policy value.
Source
Thrown at src/applications/policy/config/PolicyLockOptionType.php:30
$policy_phids = array();
foreach ($value as $capability_key => $policy) {
$capability = idx($capabilities, $capability_key);
if (!$capability) {
throw new Exception(
pht(
'Capability "%s" does not exist.',
$capability_key));
}
if (phid_get_type($policy) !=
PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
$policy_phids[$policy] = $policy;
} else {
try {
$policy_object = PhabricatorPolicyQuery::getGlobalPolicy($policy);
// this exception is not helpful here as its about global policy;
// throw a better exception
} catch (Exception $ex) {
throw new Exception(
pht(
'Capability "%s" has invalid policy "%s".',
$capability_key,
$policy));
}
}
if ($policy == PhabricatorPolicies::POLICY_PUBLIC) {
if (!$capability->shouldAllowPublicPolicySetting()) {
throw new Exception(
pht(
'Capability "%s" does not support public policy.',
$capability_key));
}
}
}
if ($policy_phids) {View on GitHub (pinned to 5720a38cfe)
Solutions
- Use the exact global policy constants from the PhabricatorPolicies class, or a real object PHID
- Copy values from the policy chooser in the UI, whose options correspond to the valid inputs
- Fix the single offending value named in the error message and re-save
Example fix
// before: not a global policy constant nor a PHID
{"diffusion.push": "all"}
// after: valid global policy constant
{"diffusion.push": "users"} Defensive patterns
Strategy: validation
Validate before calling
// Validate each policy value before saving policy.lock.
$is_phid = phid_get_type($policy) !== PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
$is_global = in_array($policy, array('public', 'users', 'admin', 'no-one'), true);
if (!$is_phid && !$is_global) {
throw new Exception(pht('Invalid policy value: %s', $policy));
} Type guard
function isValidPolicyValue($policy) {
if (!is_string($policy) || $policy === '') {
return false;
}
if (phid_get_type($policy) !== PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
return true;
}
try {
PhabricatorPolicyQuery::getGlobalPolicy($policy);
return true;
} catch (Exception $ex) {
return false;
}
} Prevention
- Source policy values from PhabricatorPolicies constants, never free text
- Validate configs in review tooling before they reach production
- Watch for casing and whitespace when editing JSON by hand
When it happens
Trigger: Saving policy.lock with a value like 'everybody', 'all-users', 'members', or a malformed PHID-like string: not a valid PHID type and not a known global policy constant.
Common situations: Guessing constant names instead of checking the PhabricatorPolicies class; configs migrated from other tools with different policy vocabulary; trailing whitespace or case changes in hand-edited JSON.
Related errors
- Capability "%s" does not exist.
- Capability "%s" does not support public policy.
- The following regex is malformed and cannot be used: %s
- You can not accept this commit because you are the commit au
- Book configuration '%s' has name '%s', but book names must i
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/509d3c2df98bc25a.
Report an issue: GitHub.