{"record":{"id":"cb100f2bf59ca7dc","repo":"phacility/phabricator","slug":"configuration-must-be-a-list-of-project-icon-speci","errorCode":null,"errorMessage":"Configuration must be a list of project icon specifications.","messagePattern":"Configuration must be a list of project icon specifications\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/project/icon/PhabricatorProjectIconSet.php","lineNumber":197,"sourceCode":"      }\n    }\n\n    return array();\n  }\n\n  public static function getMilestoneIconKey() {\n    $icons = self::getIconSpecifications();\n    foreach ($icons as $icon) {\n      if (idx($icon, 'special') === self::SPECIAL_MILESTONE) {\n        return idx($icon, 'key');\n      }\n    }\n    return null;\n  }\n\n  public static function validateConfiguration($config) {\n    if (!is_array($config)) {\n      throw new Exception(\n        pht('Configuration must be a list of project icon specifications.'));\n    }\n\n    foreach ($config as $idx => $value) {\n      if (!is_array($value)) {\n        throw new Exception(\n          pht(\n            'Value for index \"%s\" should be a dictionary.',\n            $idx));\n      }\n\n      PhutilTypeSpec::checkMap(\n        $value,\n        array(\n          'key' => 'string',\n          'name' => 'string',\n          'icon' => 'string',\n          'image' => 'optional string',","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/project/icon/PhabricatorProjectIconSet.php#L179-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"First customization of project icons, pasting a JSON blob into config without decoding it, and tooling that writes string values instead of structured ones.","solutions":["Store the value as a real JSON list: ./bin/config set projects.icons --stdin < icons.json (the set workflow json_decodes its input).","Inspect the stored value with ./bin/config get projects.icons and confirm it is a list, not a quoted string.","If you only meant to tweak one icon, start from a copy of the builtin list and keep every entry a dictionary."],"exampleFix":"// before: a string containing JSON, not a list\n[{\\\"key\\\":\\\"tag\\\"}]'   /* stored as a quoted string */\n// after: real list of dictionaries\n[{\"key\":\"tag\",\"name\":\"Tag\",\"icon\":\"fa-tags\"}]","handlingStrategy":"validation","validationCode":"$decoded = json_decode($raw, true);\nif (!is_array($decoded)) {\n  throw new Exception('projects.icons must decode to a list of icon specs');\n}","typeGuard":"function is_icon_config($value) {\n  return is_array($value);\n}","tryCatchPattern":null,"preventionTips":["Write structured config with ./bin/config set projects.icons --stdin < icons.json so values decode once.","Check ./bin/config get projects.icons reads back as a list, not a quoted string.","Never paste JSON blobs as strings into config files."],"tags":["phabricator","configuration","project-icons","type-validation"],"backgroundTag":"config-type-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}