phacility/phabricator · error · Exception

Owner rule value should be a list, but is not (value is "%s"

Error message

Owner rule value should be a list, but is not (value is "%s").

What it means

Thrown by assertValidRuleRecordFormat() when the stored value of a 'task.owner' (Assign Owner) trigger rule is not an array. The check runs in PhabricatorProjectTriggerRule::setRecord() on every load of the rule record, because downstream code (convertTokenizerValueToOwner) calls head($value) and expects a list produced by the tokenizer control.

Source

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

  public function getSelectControlName() {
    return pht('Assign task to');
  }

  protected function getValueForEditorField() {
    return $this->getDatasource()->getWireTokens($this->getValue());
  }

  private function convertTokenizerValueToOwner($value) {
    $value = head($value);
    if ($value === PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN) {
      $value = null;
    }
    return $value;
  }

  protected function assertValidRuleRecordFormat($value) {
    if (!is_array($value)) {
      throw new Exception(
        pht(
          'Owner rule value should be a list, but is not (value is "%s").',
          phutil_describe_type($value)));
    }
  }

  protected function assertValidRuleRecordValue($value) {
    if (!$value) {
      throw new Exception(
        pht(
          '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").',

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Check the rule record: SELECT * FROM phabricator_project_trigger_rule_record WHERE type='task.owner'; the value must be a JSON array.
  2. Rewrite the value as a one-element array, e.g. ["PHID-USER-abc"] or ["none()"], through the trigger editor or a repair script.
  3. Fix any import/migration code so owner values are always emitted as arrays.
  4. Verify by reloading the workboard or trigger page.

Example fix

// before
$value = 'PHID-USER-abc';

// after
$value = array('PHID-USER-abc');
Defensive patterns

Strategy: type-guard

Validate before calling

// Before writing a task.owner rule record value:
if (!is_array($value) || count($value) !== 1) {
  throw new InvalidArgumentException(
    'owner value must be a one-element list of a user PHID or "none()"');
}

Type guard

function isOwnerRuleValue($value) {
  return is_array($value) && count($value) === 1
    && (preg_match('/^PHID-USER-/', $value[0]) || $value[0] === 'none()');
}

Try / catch

try {
  $rule->setRecord($record);
} catch (Exception $ex) {
  phlog('Corrupt task.owner trigger record '.$record->getID());
  // skip this rule, continue rendering the board
}

Prevention

When it happens

Trigger: Any load of a trigger whose task.owner rule has a scalar value, e.g. value = "PHID-USER-abc" or null instead of ["PHID-USER-abc"]. Opening a workboard column with such a trigger, or editing the trigger, hits setRecord() and throws.

Common situations: Corrupt or hand-edited value column, records written by a migration/import that used a single PHID string, or a custom rule writer that skipped the tokenizer wire format.

Related errors


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