{"record":{"id":"75637f4b51714cf1","repo":"phacility/phabricator","slug":"subtype-s-is-not-valid-subtype-keys-must-be-no","errorCode":null,"errorMessage":"Subtype \"%s\" is not valid: subtype keys must be no longer than 64 bytes.","messagePattern":"Subtype \"(.+?)\" is not valid: subtype keys must be no longer than 64 bytes\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php","lineNumber":124,"sourceCode":"    }\n\n    return $view;\n  }\n\n  public function setSubtypeFieldConfiguration(\n    $subtype_key,\n    array $configuration) {\n    $this->fieldConfiguration[$subtype_key] = $configuration;\n    return $this;\n  }\n\n  public function getSubtypeFieldConfiguration($subtype_key) {\n    return idx($this->fieldConfiguration, $subtype_key);\n  }\n\n  public static function validateSubtypeKey($subtype) {\n    if (strlen($subtype) > 64) {\n      throw new Exception(\n        pht(\n          'Subtype \"%s\" is not valid: subtype keys must be no longer than '.\n          '64 bytes.',\n          $subtype));\n    }\n\n    if (strlen($subtype) < 3) {\n      throw new Exception(\n        pht(\n          'Subtype \"%s\" is not valid: subtype keys must have a minimum '.\n          'length of 3 bytes.',\n          $subtype));\n    }\n\n    if (!preg_match('/^[a-z]+\\z/', $subtype)) {\n      throw new Exception(\n        pht(\n          'Subtype \"%s\" is not valid: subtype keys may only contain '.","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php#L106-L142","documentation":"PhabricatorEditEngineSubtype::validateSubtypeKey() enforces that a subtype key is at most 64 bytes. Subtype keys come from the subtype configuration (e.g. maniphest.subtypes) and are stored on column-constrained fields, so overly long keys are rejected at validation time.","triggerScenarios":"Writing {\"key\": \"very-long-subtype-name-...>64-bytes\", ...} into the maniphest.subtypes (or another engine's) subtype configuration and saving/applying it.","commonSituations":"Teams naming subtypes after full workflow phrases instead of short slugs; pasting config from a planning doc with verbose keys.","solutions":["Shorten the key to 64 bytes or fewer — keys are slugs, put the prose in 'name'","Keep the human-readable label in the 'name' field and use a short 'key' like 'bug', 'feature', 'opsrequest'","Validate the config in a scratch/dev instance before saving it in production"],"exampleFix":"// before\n{\n  \"key\": \"security-sensitive-external-customer-escalation-request\",\n  \"name\": \"Escalation\"\n}\n\n// after\n{\n  \"key\": \"escalation\",\n  \"name\": \"Security-Sensitive External Customer Escalation Request\"\n}","handlingStrategy":"validation","validationCode":"function subtypeKeyValid($key) {\n  return is_string($key) && strlen($key) >= 3 && strlen($key) <= 64\n    && preg_match('/^[a-z]+\\z/', $key);\n}\n// Lint before saving the config:\nforeach ($config as $entry) {\n  if (!subtypeKeyValid($entry['key'])) { /* reject before save */ }\n}","typeGuard":"function isSubtypeKey($key) {\n  return is_string($key) && (bool)preg_match('/^[a-z]{3,64}\\z/', $key);\n}","tryCatchPattern":null,"preventionTips":["Treat subtype keys as slugs: short, lowercase, letter-only; put prose in 'name'","Lint the whole subtype config (keys, uniqueness, default present) in CI before deploying it","Test subtype changes on a dev instance before production"],"tags":["phabricator","subtypes","config-validation","edit-engine","php"],"backgroundTag":"config-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}