{"record":{"id":"8f08dca5cf2a9903","repo":"phacility/phabricator","slug":"capability-s-does-not-support-public-policy","errorCode":null,"errorMessage":"Capability \"%s\" does not support public policy.","messagePattern":"Capability \"(.+?)\" does not support public policy\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/policy/config/PolicyLockOptionType.php","lineNumber":40,"sourceCode":"          PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {\n        $policy_phids[$policy] = $policy;\n      } else {\n        try {\n          $policy_object = PhabricatorPolicyQuery::getGlobalPolicy($policy);\n        // this exception is not helpful here as its about global policy;\n        // throw a better exception\n        } catch (Exception $ex) {\n          throw new Exception(\n            pht(\n              'Capability \"%s\" has invalid policy \"%s\".',\n              $capability_key,\n              $policy));\n        }\n      }\n\n      if ($policy == PhabricatorPolicies::POLICY_PUBLIC) {\n        if (!$capability->shouldAllowPublicPolicySetting()) {\n          throw new Exception(\n            pht(\n              'Capability \"%s\" does not support public policy.',\n              $capability_key));\n        }\n      }\n    }\n\n    if ($policy_phids) {\n      $handles = id(new PhabricatorHandleQuery())\n        ->setViewer(PhabricatorUser::getOmnipotentUser())\n        ->withPhids($policy_phids)\n        ->execute();\n      $handles = mpull($handles, null, 'getPHID');\n      foreach ($value as $capability_key => $policy) {\n        $handle = $handles[$policy];\n        if (!$handle->isComplete()) {\n          throw new Exception(\n            pht(","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/policy/config/PolicyLockOptionType.php#L22-L58","documentation":"policy.lock may set the value 'public' (PhabricatorPolicies::POLICY_PUBLIC) only on capabilities whose implementation opts in by overriding shouldAllowPublicPolicySetting(). Most capabilities contain user-submitted data and do not opt in, so locking them to public is rejected during config validation.","triggerScenarios":"The policy.lock JSON assigns the string 'public' to a capability whose PhabricatorPolicyCapability subclass returns false from shouldAllowPublicPolicySetting().","commonSituations":"Instance admins trying to open everything to anonymous users during initial setup; copying a public-heavy config onto capabilities that never supported public policy.","solutions":["Use 'users' or another permitted policy value for that capability","Verify the capability genuinely advertises public support before attempting to lock it to public","Keep per-capability defaults from the policy UI as the source of truth for which values are acceptable"],"exampleFix":"// before: capability does not allow public policy\n{\"diffusion.push\": \"public\"}\n\n// after: use a supported policy value\n{\"diffusion.push\": \"users\"}","handlingStrategy":"validation","validationCode":"// Reject public locks on capabilities that do not allow them.\nif ($policy === PhabricatorPolicies::POLICY_PUBLIC) {\n  if (!$capability->shouldAllowPublicPolicySetting()) {\n    // fall back to an allowed policy such as POLICY_USER\n    $policy = PhabricatorPolicies::POLICY_USER;\n  }\n}","typeGuard":"function capabilityAllowsPublic(PhabricatorPolicyCapability $capability) {\n  return $capability->shouldAllowPublicPolicySetting();\n}","tryCatchPattern":null,"preventionTips":["Default to 'users' when locking policies; only use 'public' where the capability explicitly opts in","Review shouldAllowPublicPolicySetting() on the target capability before writing the config","Keep public-policy exceptions documented per capability so configs are auditable"],"tags":["phabricator","config","policy","policy-lock","public-policy"],"backgroundTag":"unsupported-config-value","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}