{"record":{"id":"5aa461c4fe62771c","repo":"phacility/phabricator","slug":"value-for-index-s-should-be-a-dictionary","errorCode":null,"errorMessage":"Value for index \"%s\" should be a dictionary.","messagePattern":"Value for index \"(.+?)\" should be a dictionary\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/project/icon/PhabricatorProjectIconSet.php","lineNumber":203,"sourceCode":"  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',\n          'special' => 'optional string',\n          'disabled' => 'optional bool',\n          'default' => 'optional bool',\n        ));\n\n      if (!preg_match('/^[a-z]{1,32}\\z/', $value['key'])) {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/project/icon/PhabricatorProjectIconSet.php#L185-L221","documentation":"Each element of projects.icons must itself be an array — one dictionary describing one icon. A scalar entry (string, number, bool) throws with the offending index; after this check, each dictionary's fields are verified by PhutilTypeSpec::checkMap.","triggerScenarios":"A list like [\"tag\", {...}] where one entry is a bare string instead of a {\"key\": ...} dictionary.","commonSituations":"Hand-trimming config for brevity and replacing a dict with just its key, and merging config fragments from different sources.","solutions":["Wrap every entry in an object with at least key, name, and icon.","Decode the payload in a scratch script and assert every element is an array before saving."],"exampleFix":"// before\n[{\"key\":\"tag\",\"name\":\"Tag\",\"icon\":\"fa-tags\"}, \"group\"]\n// after\n[{\"key\":\"tag\",\"name\":\"Tag\",\"icon\":\"fa-tags\"},\n {\"key\":\"group\",\"name\":\"Group\",\"icon\":\"fa-users\"}]","handlingStrategy":"validation","validationCode":"foreach ($config as $idx => $entry) {\n  if (!is_array($entry)) {\n    throw new Exception(sprintf('entry %d is not a dictionary', $idx));\n  }\n}","typeGuard":"function is_icon_spec($entry) {\n  return is_array($entry)\n    && isset($entry['key'], $entry['name'], $entry['icon']);\n}","tryCatchPattern":null,"preventionTips":["Every icon entry is a dictionary with at least key, name, icon.","Validate the full list in a scratch script before saving it to config."],"tags":["phabricator","configuration","project-icons","schema-validation"],"backgroundTag":"config-schema-validation","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}