{"record":{"id":"1e0c42870a98dddb","repo":"phacility/phabricator","slug":"status-rule-value-should-be-a-string-but-is-not","errorCode":null,"errorMessage":"Status rule value should be a string, but is not (value is \"%s\").","messagePattern":"Status rule value should be a string, but is not \\(value is \"(.+?)\"\\)\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/project/trigger/PhabricatorProjectTriggerManiphestStatusRule.php","lineNumber":14,"sourceCode":"<?php\n\nfinal class PhabricatorProjectTriggerManiphestStatusRule\n  extends PhabricatorProjectTriggerRule {\n\n  const TRIGGERTYPE = 'task.status';\n\n  public function getSelectControlName() {\n    return pht('Change status to');\n  }\n\n  protected function assertValidRuleRecordFormat($value) {\n    if (!is_string($value)) {\n      throw new Exception(\n        pht(\n          'Status rule value should be a string, but is not (value is \"%s\").',\n          phutil_describe_type($value)));\n    }\n  }\n\n  protected function assertValidRuleRecordValue($value) {\n    $map = ManiphestTaskStatus::getTaskStatusMap();\n    if (!isset($map[$value])) {\n      throw new Exception(\n        pht(\n          'Task status value (\"%s\") is not a valid task status. '.\n          'Valid statues are: %s.',\n          $value,\n          implode(', ', array_keys($map))));\n    }\n  }\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/project/trigger/PhabricatorProjectTriggerManiphestStatusRule.php#L1-L32","documentation":"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().","triggerScenarios":"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().","commonSituations":"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.","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."],"exampleFix":"// before\n$value = array('resolved');\n\n// after\n$value = 'resolved';","handlingStrategy":"type-guard","validationCode":"if (!is_string($value)) {\n  throw new InvalidArgumentException('status value must be a string key');\n}","typeGuard":"function isStatusRuleValue($value) {\n  return is_string($value)\n    && isset(ManiphestTaskStatus::getTaskStatusMap()[$value]);\n}","tryCatchPattern":"try {\n  $rule->setRecord($record);\n} catch (Exception $ex) {\n  phlog('Corrupt task.status record '.$record->getID());\n  continue;\n}","preventionTips":["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."],"tags":["php","phabricator","project-triggers","workboard","data-corruption"],"backgroundTag":"stored-config-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}