{"record":{"id":"07c5eb5e60bb9114","repo":"phacility/phabricator","slug":"capability-s-has-invalid-policy-s-s-does","errorCode":null,"errorMessage":"Capability \"%s\" has invalid policy \"%s\"; \"%s\" does not exist.","messagePattern":"Capability \"(.+?)\" has invalid policy \"(.+?)\"; \"(.+?)\" does not exist\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/policy/config/PolicyLockOptionType.php","lineNumber":57,"sourceCode":"        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(\n              'Capability \"%s\" has invalid policy \"%s\"; \"%s\" does not exist.',\n              $capability_key,\n              $policy,\n              $policy));\n        }\n      }\n    }\n  }\n\n}\n","sourceCodeStart":39,"sourceCodeEnd":69,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/policy/config/PolicyLockOptionType.php#L39-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Copy the policy PHID out of the message and verify it resolves: ./bin/phid lookup 'PHID-PROJ-...'","If the referenced object is gone, create or pick an existing project, put its PHID into policy.lock, and save again.","If locking is no longer wanted, clear the option: ./bin/config delete policy.lock"],"exampleFix":"// before: config points at a project that was deleted\n{\"view\": \"PHID-PROJ-4b2zdeadbeef\"}\n// after: PHID verified with ./bin/phid lookup, points at an existing project\n{\"view\": \"PHID-PROJ-7f3alive42\"}","handlingStrategy":"validation","validationCode":"// Before saving policy.lock, confirm every policy PHID resolves.\nforeach (array_values($lock_map) as $phid) {\n  $handle = id(new PhabricatorHandleQuery())\n    ->setViewer(PhabricatorUser::getOmnipotentUser())\n    ->withPHIDs(array($phid))\n    ->executeOne();\n  if (!$handle || !$handle->isComplete()) {\n    throw new Exception(pht('Policy PHID %s does not resolve; refusing to save.', $phid));\n  }\n}\n// CLI equivalent: ./bin/phid lookup PHID-PROJ-xxx","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Resolve every policy PHID with ./bin/phid lookup before writing policy.lock.","Never copy policy PHIDs between Phabricator instances; re-derive them per install.","Lock to stable, long-lived projects unlikely to be deleted."],"tags":["phabricator","policy","configuration","phid","dangling-reference","policy-lock"],"backgroundTag":"dangling-config-reference","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}