phacility/phabricator · error · Exception
Add project rule value should be a list, but is not (value i
Error message
Add project 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.projects.add' (Add Projects) trigger rule is not a PHP array. The check runs in PhabricatorProjectTriggerRule::setRecord(), which executes every time a trigger rule record is loaded from the database (workboard rendering, trigger editing, card drop). It means the JSON in PhabricatorProjectTriggerRuleRecord.value is corrupt or was written with the wrong shape.
Source
Thrown at src/applications/project/trigger/PhabricatorProjectTriggerAddProjectsRule.php:18
<?php
final class PhabricatorProjectTriggerAddProjectsRule
extends PhabricatorProjectTriggerRule {
const TRIGGERTYPE = 'task.projects.add';
public function getSelectControlName() {
return pht('Add project tags');
}
protected function getValueForEditorField() {
return $this->getDatasource()->getWireTokens($this->getValue());
}
protected function assertValidRuleRecordFormat($value) {
if (!is_array($value)) {
throw new Exception(
pht(
'Add project 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(
'You must select at least one project tag to add.'));
}
}
protected function newDropTransactions($object, $value) {
$project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
View on GitHub (pinned to 5720a38cfe)
Solutions
- Inspect the row: SELECT * FROM phabricator_project_trigger_rule_record WHERE type='task.projects.add' and confirm the value column holds a JSON list.
- Fix the stored value to a JSON array of project PHIDs, e.g. ["PHID-PROJ-xyz"], via the trigger editor (preferred) or a storage repair script.
- If the record came from an import/migration, correct the writer so it always emits an array for tokenizer-backed rules.
- After repair, reload the workboard or trigger edit page to confirm setRecord() no longer throws.
Example fix
// before: trigger rule record value (corrupt)
$value = 'PHID-PROJ-xyz';
// after: list of project PHIDs
$value = array('PHID-PROJ-xyz'); Defensive patterns
Strategy: type-guard
Validate before calling
// Before writing a task.projects.add rule record value:
if (!is_array($value)) {
throw new InvalidArgumentException('add-projects value must be a list of project PHIDs');
}
PhutilTypeSpec::checkMap... // or simply:
assert(is_array($value)); Type guard
function isAddProjectsRuleValue($value) {
return is_array($value) && !empty($value)
&& preg_match('/^PHID-PROJ-/', implode(',', $value));
} Try / catch
try {
$rule->setRecord($record);
} catch (Exception $ex) {
// Corrupt stored trigger: log record ID, quarantine rule, keep board usable
phlog($ex);
$rule = null;
} Prevention
- Always create trigger records through the trigger editor or the standard editor APIs so value shapes match the rule type.
- Validate value shape (is_array for list rules) before persisting PhabricatorProjectTriggerRuleRecord rows.
- Back up and dry-run any script that bulk-edits phabricator_project_trigger_rule_record.
When it happens
Trigger: Loading or saving any trigger whose rule of type 'task.projects.add' has a non-list value, e.g. the value column contains a bare PHID string instead of a JSON array of PHIDs. Reproduce with: a trigger record where phabricator_project_trigger_rule_record.value = "PHID-PROJ-xyz" instead of ["PHID-PROJ-xyz"], then open a workboard that uses the trigger.
Common situations: Hand-edited database rows, a migration or import script that wrote scalar values, an older Phorge/Phabricator version that stored the value differently, or a custom code path calling setRecord() with a hand-built record object.
Related errors
- Owner rule value should be a list, but is not (value is "%s"
- Priority rule value should be a string, but is not (value is
- Status rule value should be a string, but is not (value is "
- Remove project rule value should be a list, but is not (valu
- Status rule value should be a string, but is not (value is "
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/645ae956605f57e1.
Report an issue: GitHub.