phacility/phabricator · error · Exception

Configuration must be a list of project icon specifications.

Error message

Configuration must be a list of project icon specifications.

What it means

PhabricatorProjectIconSet::validateConfiguration() validates the projects.icons configuration. The top-level value must be a PHP array serving as a list of icon specification dictionaries; any scalar — classically a JSON string that was double-encoded — throws immediately, before any entry is inspected.

Source

Thrown at src/applications/project/icon/PhabricatorProjectIconSet.php:197

      }
    }

    return array();
  }

  public static function getMilestoneIconKey() {
    $icons = self::getIconSpecifications();
    foreach ($icons as $icon) {
      if (idx($icon, 'special') === self::SPECIAL_MILESTONE) {
        return idx($icon, 'key');
      }
    }
    return null;
  }

  public static function validateConfiguration($config) {
    if (!is_array($config)) {
      throw new Exception(
        pht('Configuration must be a list of project icon specifications.'));
    }

    foreach ($config as $idx => $value) {
      if (!is_array($value)) {
        throw new Exception(
          pht(
            'Value for index "%s" should be a dictionary.',
            $idx));
      }

      PhutilTypeSpec::checkMap(
        $value,
        array(
          'key' => 'string',
          'name' => 'string',
          'icon' => 'string',
          'image' => 'optional string',

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Store the value as a real JSON list: ./bin/config set projects.icons --stdin < icons.json (the set workflow json_decodes its input).
  2. Inspect the stored value with ./bin/config get projects.icons and confirm it is a list, not a quoted string.
  3. If you only meant to tweak one icon, start from a copy of the builtin list and keep every entry a dictionary.

Example fix

// before: a string containing JSON, not a list
[{\"key\":\"tag\"}]'   /* stored as a quoted string */
// after: real list of dictionaries
[{"key":"tag","name":"Tag","icon":"fa-tags"}]
Defensive patterns

Strategy: validation

Validate before calling

$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
  throw new Exception('projects.icons must decode to a list of icon specs');
}

Type guard

function is_icon_config($value) {
  return is_array($value);
}

Prevention

When it happens

Trigger: Setting projects.icons to a raw JSON string instead of a decoded array (e.g. double-encoding when writing config), or to any non-array value, then loading the icon set.

Common situations: First customization of project icons, pasting a JSON blob into config without decoding it, and tooling that writes string values instead of structured ones.

Related errors


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