phacility/phabricator · error · Exception
Status rule value should be a string, but is not (value is "
Error message
Status 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.status' trigger rule is not a string. It runs in PhabricatorProjectTriggerRule::setRecord() on every load, because assertValidRuleRecordValue() will use the value as a status key into ManiphestTaskStatus::getTaskStatusMap().
Source
Thrown at src/applications/project/trigger/PhabricatorProjectTriggerManiphestStatusRule.php:14
<?php
final class PhabricatorProjectTriggerManiphestStatusRule
extends PhabricatorProjectTriggerRule {
const TRIGGERTYPE = 'task.status';
public function getSelectControlName() {
return pht('Change status to');
}
protected function assertValidRuleRecordFormat($value) {
if (!is_string($value)) {
throw new Exception(
pht(
'Status rule value should be a string, but is not (value is "%s").',
phutil_describe_type($value)));
}
}
protected function assertValidRuleRecordValue($value) {
$map = ManiphestTaskStatus::getTaskStatusMap();
if (!isset($map[$value])) {
throw new Exception(
pht(
'Task status value ("%s") is not a valid task status. '.
'Valid statues are: %s.',
$value,
implode(', ', array_keys($map))));
}
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Locate the row: SELECT * FROM phabricator_project_trigger_rule_record WHERE type='task.status'; and inspect value.
- Rewrite the value to a string status key, e.g. "resolved", via the trigger editor or repair script.
- Correct any import/migration logic to store scalar status keys.
- Confirm the workboard renders after the fix.
Example fix
// before
$value = array('resolved');
// after
$value = 'resolved'; Defensive patterns
Strategy: type-guard
Validate before calling
if (!is_string($value)) {
throw new InvalidArgumentException('status value must be a string key');
} Type guard
function isStatusRuleValue($value) {
return is_string($value)
&& isset(ManiphestTaskStatus::getTaskStatusMap()[$value]);
} Try / catch
try {
$rule->setRecord($record);
} catch (Exception $ex) {
phlog('Corrupt task.status record '.$record->getID());
continue;
} Prevention
- Status rules store one scalar key; never wrap in an array.
- Check json types after imports: task.status values must decode to strings.
- Cover each rule type with a fixture test that setRecord() accepts.
When it happens
Trigger: A task.status rule whose value column holds an array, integer, or null instead of a status key string like 'open' or 'resolved'. Any load path — workboard render, trigger edit, card drop — throws from setRecord().
Common situations: Hand-edited or imported rows with wrong JSON shape; a custom writer reused the array format of tokenizer rules for the status rule; older version wrote a different shape.
Related errors
- Add project rule value should be a list, but is not (value i
- 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
- 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/1e0c42870a98dddb.
Report an issue: GitHub.