{"record":{"id":"bd22ea639fb6b813","repo":"phacility/phabricator","slug":"subtype-s-is-not-valid-subtype-keys-may-only-c","errorCode":null,"errorMessage":"Subtype \"%s\" is not valid: subtype keys may only contain lowercase latin letters (\"a\" through \"z\").","messagePattern":"Subtype \"(.+?)\" is not valid: subtype keys may only contain lowercase latin letters \\(\"a\" through \"z\"\\)\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php","lineNumber":140,"sourceCode":"  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 '.\n          'lowercase latin letters (\"a\" through \"z\").',\n          $subtype));\n    }\n  }\n\n  public static function validateConfiguration($config) {\n    if (!is_array($config)) {\n      throw new Exception(\n        pht(\n          'Subtype configuration is invalid: it must be a list of subtype '.\n          'specifications.'));\n    }\n\n    $map = array();\n    foreach ($config as $value) {\n      PhutilTypeSpec::checkMap(","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php#L122-L158","documentation":"The third rule in validateSubtypeKey(): the key must match /^[a-z]+\\z/ — lowercase latin letters only, no digits, hyphens, underscores, uppercase, or whitespace. Keys become part of identifiers and UI markers, so the alphabet is intentionally strict.","triggerScenarios":"Saving subtype config with keys like \"task-2\", \"feature_request\", \"Bug\", \"ops1\", or keys containing spaces or unicode.","commonSituations":"Copying keys from external trackers (Jira issue types like \"sub-task\", GitHub labels with hyphens); numbering subtypes (\"task1\", \"task2\"); capitalized names pasted from a spreadsheet.","solutions":["Use pure lowercase a–z runs: \"subtask\", \"feature\", \"opsrequest\", \"securitytask\"","Strip hyphens/underscores/digits and lowercase the key when migrating from external systems","Put separators or numbering in the 'name', never in the 'key'"],"exampleFix":"// before\n{ \"key\": \"sub-task\", \"name\": \"Sub-Task\" }\n// Exception: subtype keys may only contain lowercase latin letters.\n\n// after\n{ \"key\": \"subtask\", \"name\": \"Sub-Task\" }","handlingStrategy":"validation","validationCode":"if (!preg_match('/^[a-z]+\\z/', $key)) {\n  $key = preg_replace('/[^a-z]/', '', strtolower($key));\n  // re-check length, then use the cleaned key\n}","typeGuard":"function isSubtypeKey($key) {\n  return is_string($key) && (bool)preg_match('/^[a-z]{3,64}\\z/', $key);\n}","tryCatchPattern":null,"preventionTips":["Lowercase and strip non-letters when importing keys from external trackers","No hyphens, underscores, digits, or capitals in keys — ever","Put numbering/formatting in 'name', keep 'key' a plain a–z run"],"tags":["phabricator","subtypes","config-validation","identifier-format","php"],"backgroundTag":"config-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}