phacility/phabricator · error · Exception

Object view policy can not be unlocked because this object d

Error message

Object view policy can not be unlocked because this object does not have a mutable view policy.

What it means

newUnlockViewTransactions() builds a view-policy transaction that hands the object to the unlocking user, but first asks the object's application editor which transaction types it can apply (canApplyTransactionType()). If TYPE_VIEW_POLICY is not supported for the object, its view policy is immutable through transactions and the unlock is refused.

Source

Thrown at src/applications/system/engine/PhabricatorUnlockEngine.php:29

          'of object can not be unlocked.',
          phutil_describe_type($object),
          'PhabricatorApplicationTransactionInterface'));
    }

    if ($object instanceof PhabricatorUnlockableInterface) {
      $engine = $object->newUnlockEngine();
    } else {
      $engine = new PhabricatorDefaultUnlockEngine();
    }

    return $engine;
  }

  public function newUnlockViewTransactions($object, $user) {
    $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;

    if (!$this->canApplyTransactionType($object, $type_view)) {
      throw new Exception(
        pht(
          'Object view policy can not be unlocked because this object '.
          'does not have a mutable view policy.'));
    }

    return array(
      $this->newTransaction($object)
        ->setTransactionType($type_view)
        ->setNewValue($user->getPHID()),
    );
  }

  public function newUnlockEditTransactions($object, $user) {
    $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;

    if (!$this->canApplyTransactionType($object, $type_edit)) {
      throw new Exception(
        pht(

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Try the edit-policy or owner unlock variants instead; one of them is usually supported for the type
  2. If this is your application's editor, add TYPE_VIEW_POLICY to the transaction types it supports for the object
  3. Use the object type's dedicated administrative recovery workflow if one exists

Example fix

// before
$xactions = $engine->newUnlockViewTransactions($object, $user);

// after: only request view-policy unlock when the editor supports it
$types = array_fuse(
  $object->getApplicationTransactionEditor()
    ->getTransactionTypesForObject($object));
if (!isset($types[PhabricatorTransactions::TYPE_VIEW_POLICY])) {
  return pht('View policy can not be unlocked for this object.');
}
$xactions = $engine->newUnlockViewTransactions($object, $user);
Defensive patterns

Strategy: type-guard

Validate before calling

$types = array_fuse(
  $object->getApplicationTransactionEditor()
    ->getTransactionTypesForObject($object));
if (isset($types[PhabricatorTransactions::TYPE_VIEW_POLICY])) {
  $xactions = $engine->newUnlockViewTransactions($object, $user);
} else {
  // offer edit-policy or owner unlock instead
}

Type guard

function hasMutableViewPolicy($object) {
  $types = array_fuse(
    $object->getApplicationTransactionEditor()
      ->getTransactionTypesForObject($object));
  return isset($types[PhabricatorTransactions::TYPE_VIEW_POLICY]);
}

Prevention

When it happens

Trigger: Requesting a view-policy unlock on an object whose editor does not return PhabricatorTransactions::TYPE_VIEW_POLICY from getTransactionTypesForObject(): types with fixed or hereditary view policies, or custom editors that never declared policy transaction types.

Common situations: Recovery attempts on policy-locked records whose type does not support view-policy edits; custom applications that forgot to include policy transaction types in their editor.

Related errors


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