phacility/phabricator · error · Exception

User PHID ("%s") is not a valid user.

Error message

User PHID ("%s") is not a valid user.

What it means

Thrown by assertValidRuleRecordValue() for the 'task.owner' rule when the selected PHID does not resolve to a visible user. The rule loads the PHID with PhabricatorPeopleQuery under the current viewer; if executeOne() returns nothing (unknown PHID, deleted/disabled user, or policy-hidden user), it throws.

Source

Thrown at src/applications/project/trigger/PhabricatorProjectTriggerManiphestOwnerRule.php:55

          'Owner rule value is required. Specify a user to assign tasks '.
          'to, or the token "none()" to unassign tasks.'));
    }

    if (count($value) > 1) {
      throw new Exception(
        pht(
          'Owner rule value must have only one elmement (value is "%s").',
          implode(', ', $value)));
    }

    $owner_phid = $this->convertTokenizerValueToOwner($value);
    if ($owner_phid !== null) {
      $user = id(new PhabricatorPeopleQuery())
        ->setViewer($this->getViewer())
        ->withPHIDs(array($owner_phid))
        ->executeOne();
      if (!$user) {
        throw new Exception(
          pht(
            'User PHID ("%s") is not a valid user.',
            $owner_phid));
      }
    }
  }

  protected function newDropTransactions($object, $value) {
    $value = $this->convertTokenizerValueToOwner($value);
    return array(
      $this->newTransaction()
        ->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE)
        ->setNewValue($value),
    );
  }

  protected function newDropEffects($value) {
    $owner_value = $this->convertTokenizerValueToOwner($value);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Open the trigger and re-pick the owner from the tokenizer so a fresh, valid PHID is stored, or use none().
  2. If the owner left, update the trigger to their replacement or to none() to unassign tasks.
  3. For cross-instance imports, remap user PHIDs before importing trigger records.
  4. Confirm the viewer that validates/applies the trigger can see the target user under policies.

Example fix

// before
$value = array('PHID-USER-deleted');

// after
$value = array('PHID-USER-current');
// or: $value = array('none()');
Defensive patterns

Strategy: validation

Validate before calling

// Validate the owner resolves before saving:
$user = id(new PhabricatorPeopleQuery())
  ->setViewer($viewer)
  ->withPHIDs(array($owner_phid))
  ->executeOne();
if (!$user) {
  throw new Exception('Owner PHID does not resolve; pick a user or use none().');
}

Type guard

function isResolvableOwnerPhid($viewer, $phid) {
  if ($phid === null || $phid === 'none()') { return true; }
  return (bool) id(new PhabricatorPeopleQuery())
    ->setViewer($viewer)
    ->withPHIDs(array($phid))
    ->executeOne();
}

Try / catch

$ex = $rule->getRuleRecordValueValidationException();
if ($ex) { /* prompt user to re-pick owner; suggest none() */ }

Prevention

When it happens

Trigger: A task.owner rule holding a stale PHID (e.g. PHID-USER of an account deleted since the trigger was created), a malformed PHID, or a user the acting viewer cannot see. Surfaces when the trigger editor validates/saves, and when the rule is checked while applying the trigger.

Common situations: User account deleted or disabled after the trigger was configured; data imported between instances so PHIDs do not match; typo'd PHID in a hand-built record; the daemon/acting user lacks permission to see the owner.

Related errors


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