{"record":{"id":"d90d5a2de0c05844","repo":"phacility/phabricator","slug":"keyring-configuration-has-an-invalid-key-specifica","errorCode":null,"errorMessage":"Keyring configuration has an invalid key specification (at index \"%s\"): %s.","messagePattern":"Keyring configuration has an invalid key specification \\(at index \"(.+?)\"\\): (.+?)\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/files/keyring/PhabricatorKeyringConfigOptionType.php","lineNumber":39,"sourceCode":"            $index));\n      }\n    }\n\n\n    $map = array();\n    $defaults = array();\n    foreach ($value as $index => $spec) {\n      try {\n        PhutilTypeSpec::checkMap(\n          $spec,\n          array(\n            'name' => 'string',\n            'type' => 'string',\n            'material.base64' => 'string',\n            'default' => 'optional bool',\n          ));\n      } catch (Exception $ex) {\n        throw new Exception(\n          pht(\n            'Keyring configuration has an invalid key specification (at '.\n            'index \"%s\"): %s.',\n            $index,\n            $ex->getMessage()));\n      }\n\n      $name = $spec['name'];\n      if (isset($map[$name])) {\n        throw new Exception(\n          pht(\n            'Keyring configuration is invalid: it describes multiple keys '.\n            'with the same name (\"%s\"). Each key must have a unique name.',\n            $name));\n      }\n      $map[$name] = true;\n\n      if (idx($spec, 'default')) {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/files/keyring/PhabricatorKeyringConfigOptionType.php#L21-L57","documentation":"Each key dictionary in the keyring config is checked with PhutilTypeSpec::checkMap() against the exact schema {name: string, type: string, material.base64: string, default: optional bool}. This error wraps any schema violation and includes the list index plus the underlying spec message, which names the offending field. Unknown keys and wrong scalar types are both rejected.","triggerScenarios":"An entry missing material.base64; using 'material' instead of 'material.base64'; name given as a number instead of a string; adding an undocumented extra field such as 'comment'; default set to \"true\" (string) instead of true (bool).","commonSituations":"Hand-writing or templating the keyring JSON; field names remembered from an older document; YAML-to-JSON conversion coercing booleans to strings.","solutions":["Match the exact field set: name (string), type (string), material.base64 (string), default (optional bool)","Read the %s suffix of the message — it is the PhutilTypeSpec error naming the bad field and expected type","Remove extra fields; Phabricator rejects unknown keys rather than ignoring them"],"exampleFix":"// before\n[{\"name\": \"prod\", \"type\": \"aes-256-cbc\", \"material\": \"...==\", \"default\": \"true\"}]\n\n// after\n[{\"name\": \"prod\", \"type\": \"aes-256-cbc\", \"material.base64\": \"...==\", \"default\": true}]","handlingStrategy":"validation","validationCode":"// Mirror the schema check before saving:\nPhutilTypeSpec::checkMap(\n  $spec,\n  array(\n    'name' => 'string',\n    'type' => 'string',\n    'material.base64' => 'string',\n    'default' => 'optional bool',\n  ));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use exactly the four allowed fields: name, type, material.base64, default","Booleans must be JSON true/false, not \"true\"/\"false\" strings","Run the PhutilTypeSpec check in config pipelines to catch field errors before deployment"],"tags":["config","json","keyring","schema","validation","phabricator"],"backgroundTag":"config-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}