phacility/phabricator · error · Exception

Priority rule value should be a string, but is not (value is

Error message

Priority rule value should be a string, but is not (value is "%s").

What it means

Thrown by assertValidRuleRecordFormat() when the stored value of a 'task.priority' trigger rule is not a string. The check runs in PhabricatorProjectTriggerRule::setRecord() on every load of the rule record, because the rest of the rule treats the value as a priority keyword string looked up in ManiphestTaskPriority::getTaskPriorityMap().

Source

Thrown at src/applications/project/trigger/PhabricatorProjectTriggerManiphestPriorityRule.php:14

<?php

final class PhabricatorProjectTriggerManiphestPriorityRule
  extends PhabricatorProjectTriggerRule {

  const TRIGGERTYPE = 'task.priority';

  public function getSelectControlName() {
    return pht('Change priority to');
  }

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

  protected function assertValidRuleRecordValue($value) {
    $map = ManiphestTaskPriority::getTaskPriorityMap();
    if (!isset($map[$value])) {
      throw new Exception(
        pht(
          'Task priority value ("%s") is not a valid task priority. '.
          'Valid priorities are: %s.',
          $value,
          implode(', ', array_keys($map))));
    }
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Find the offending row: SELECT * FROM phabricator_project_trigger_rule_record WHERE type='task.priority'; and check the value type.
  2. Rewrite the value as a string keyword, e.g. "100", via the editor or a repair script.
  3. Fix import code to cast priority keywords to strings before storing.
  4. Reload the workboard/trigger to confirm the rule renders.

Example fix

// before
$value = 100;

// after
$value = '100';
Defensive patterns

Strategy: type-guard

Validate before calling

// Before writing a task.priority rule record value:
if (!is_string($value)) {
  throw new InvalidArgumentException('priority value must be a string keyword');
}

Type guard

function isPriorityRuleValue($value) {
  return is_string($value)
    && isset(ManiphestTaskPriority::getTaskPriorityMap()[$value]);
}

Try / catch

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

Prevention

When it happens

Trigger: A task.priority rule whose value column holds an integer (e.g. 100 instead of '100'), an array, or null. Loading the trigger on a workboard, editing it, or dropping a card onto its column invokes setRecord() and throws immediately.

Common situations: Import/migration wrote the numeric priority as a PHP/JSON number; hand-edited DB row; custom code built the record with an int from getTaskPriorityMap() keys without casting.

Related errors


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