phacility/phabricator · error · Exception

Subtype "%s" is not valid: subtype keys may only contain low

Error message

Subtype "%s" is not valid: subtype keys may only contain lowercase latin letters ("a" through "z").

What it means

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.

Source

Thrown at src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php:140

  public static function validateSubtypeKey($subtype) {
    if (strlen($subtype) > 64) {
      throw new Exception(
        pht(
          'Subtype "%s" is not valid: subtype keys must be no longer than '.
          '64 bytes.',
          $subtype));
    }

    if (strlen($subtype) < 3) {
      throw new Exception(
        pht(
          'Subtype "%s" is not valid: subtype keys must have a minimum '.
          'length of 3 bytes.',
          $subtype));
    }

    if (!preg_match('/^[a-z]+\z/', $subtype)) {
      throw new Exception(
        pht(
          'Subtype "%s" is not valid: subtype keys may only contain '.
          'lowercase latin letters ("a" through "z").',
          $subtype));
    }
  }

  public static function validateConfiguration($config) {
    if (!is_array($config)) {
      throw new Exception(
        pht(
          'Subtype configuration is invalid: it must be a list of subtype '.
          'specifications.'));
    }

    $map = array();
    foreach ($config as $value) {
      PhutilTypeSpec::checkMap(

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Use pure lowercase a–z runs: "subtask", "feature", "opsrequest", "securitytask"
  2. Strip hyphens/underscores/digits and lowercase the key when migrating from external systems
  3. Put separators or numbering in the 'name', never in the 'key'

Example fix

// before
{ "key": "sub-task", "name": "Sub-Task" }
// Exception: subtype keys may only contain lowercase latin letters.

// after
{ "key": "subtask", "name": "Sub-Task" }
Defensive patterns

Strategy: validation

Validate before calling

if (!preg_match('/^[a-z]+\z/', $key)) {
  $key = preg_replace('/[^a-z]/', '', strtolower($key));
  // re-check length, then use the cleaned key
}

Type guard

function isSubtypeKey($key) {
  return is_string($key) && (bool)preg_match('/^[a-z]{3,64}\z/', $key);
}

Prevention

When it happens

Trigger: Saving subtype config with keys like "task-2", "feature_request", "Bug", "ops1", or keys containing spaces or unicode.

Common situations: 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.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/bd22ea639fb6b813. Report an issue: GitHub.