phacility/phabricator · error · Exception

Subtype configuration is invalid: subtype with key "%s" spec

Error message

Subtype configuration is invalid: subtype with key "%s" specifies both child subtypes and child forms. Specify one or the other, but not both.

What it means

A subtype's optional "children" block may define either "subtypes" (child subtype keys the create flow offers) or "forms" (specific form identifiers/markers to offer), but not both — they are two mutually exclusive mechanisms for declaring child creation forms. validateConfiguration() rejects entries that set both.

Source

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

            'Subtype configuration is invalid: subtype with key "%s" has '.
            'no name. Subtypes must have a name.',
            $key));
      }

      $children = idx($value, 'children');
      if ($children) {
        PhutilTypeSpec::checkMap(
          $children,
          array(
            'subtypes' => 'optional list<string>',
            'forms' => 'optional list<string|int>',
          ));

        $child_subtypes = idx($children, 'subtypes');
        $child_forms = idx($children, 'forms');

        if ($child_subtypes && $child_forms) {
          throw new Exception(
            pht(
              'Subtype configuration is invalid: subtype with key "%s" '.
              'specifies both child subtypes and child forms. Specify one '.
              'or the other, but not both.',
              $key));
        }
      }

      $fields = idx($value, 'fields');
      if ($fields) {
        foreach ($fields as $field_key => $configuration) {
          PhutilTypeSpec::checkMap(
            $configuration,
            array(
              'disabled' => 'optional bool',
              'name' => 'optional string',
            ));
        }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Keep exactly one of "subtypes" or "forms" in each children block and delete the other
  2. Prefer "subtypes" when the children are ordinary subtypes; use "forms" only when you must point at specific form identifiers/markers
  3. After fixing, re-check that referenced child subtype keys still exist in the config

Example fix

// before
{
  "key": "parent", "name": "Parent",
  "children": {
    "subtypes": ["childa", "childb"],
    "forms": ["task.form.c1"]
  }
}

// after
{
  "key": "parent", "name": "Parent",
  "children": {
    "subtypes": ["childa", "childb"]
  }
}
Defensive patterns

Strategy: validation

Validate before calling

foreach ($config as $entry) {
  $children = idx($entry, 'children');
  if ($children) {
    if (!empty($children['subtypes']) && !empty($children['forms'])) {
      // reject before saving: choose one mechanism only
    }
  }
}

Type guard

function childrenBlockExclusive(array $children) {
  return !( !empty($children['subtypes']) && !empty($children['forms']) );
}

Prevention

When it happens

Trigger: Config such as {"key": "parent", "name": "Parent", "children": {"subtypes": ["childa"], "forms": ["task.form.c2" ]}} — both keys non-empty inside the same children block.

Common situations: Migrating from subtype-based child forms to explicit form-based children and leaving the old key in place; merging two example configs; misunderstanding that "forms" replaces rather than supplements "subtypes".

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/7f3081ba5e540260. Report an issue: GitHub.