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 'sound' (Play Sound) trigger rule is not a string. It runs in PhabricatorProjectTriggerRule::setRecord() on every rule load. Note the message text says 'Status rule value' — an upstream copy-paste from the status rule — but this validates the sound rule.

Source

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

<?php

final class PhabricatorProjectTriggerPlaySoundRule
  extends PhabricatorProjectTriggerRule {

  const TRIGGERTYPE = 'sound';

  public function getSelectControlName() {
    return pht('Play sound');
  }

  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 = self::getSoundMap();
    if (!isset($map[$value])) {
      throw new Exception(
        pht(
          'Sound ("%s") is not a valid sound.',
          $value));
    }
  }

  protected function newDropTransactions($object, $value) {
    return array();

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Find the row: SELECT * FROM phabricator_project_trigger_rule_record WHERE type='sound'; and check the value type.
  2. Rewrite the value to a string sound key accepted by PhabricatorProjectTriggerPlaySoundRule::getSoundMap(), e.g. via the trigger editor.
  3. Fix the writer/importer that produced the non-string value.
  4. Verify the workboard loads afterwards.

Example fix

// before
$value = array('bing');

// after (a key from getSoundMap())
$value = 'bing';
Defensive patterns

Strategy: type-guard

Validate before calling

if (!is_string($value)) {
  throw new InvalidArgumentException('sound value must be a string key');
}

Type guard

function isSoundRuleValue($value) {
  return is_string($value) && $value !== '';
}

Try / catch

try {
  $rule->setRecord($record);
} catch (Exception $ex) {
  // note: upstream message says 'Status rule value' for sound rules
  phlog('Corrupt sound trigger record '.$record->getID());
  continue;
}

Prevention

When it happens

Trigger: A 'sound' rule whose value column holds a non-string (array, int, null) instead of a sound key string. Rendering a workboard that uses the trigger, editing the trigger, or dropping a card hits setRecord() and throws.

Common situations: Hand-edited DB value; import script wrote the sound as a list; corrupt JSON after a partial migration.

Related errors


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