{"record":{"id":"7f3081ba5e540260","repo":"phacility/phabricator","slug":"subtype-configuration-is-invalid-subtype-with-key-7f3081","errorCode":null,"errorMessage":"Subtype configuration is invalid: subtype with key \"%s\" specifies both child subtypes and child forms. Specify one or the other, but not both.","messagePattern":"Subtype configuration is invalid: subtype with key \"(.+?)\" specifies both child subtypes and child forms\\. Specify one or the other, but not both\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php","lineNumber":206,"sourceCode":"            'Subtype configuration is invalid: subtype with key \"%s\" has '.\n            'no name. Subtypes must have a name.',\n            $key));\n      }\n\n      $children = idx($value, 'children');\n      if ($children) {\n        PhutilTypeSpec::checkMap(\n          $children,\n          array(\n            'subtypes' => 'optional list<string>',\n            'forms' => 'optional list<string|int>',\n          ));\n\n        $child_subtypes = idx($children, 'subtypes');\n        $child_forms = idx($children, 'forms');\n\n        if ($child_subtypes && $child_forms) {\n          throw new Exception(\n            pht(\n              'Subtype configuration is invalid: subtype with key \"%s\" '.\n              'specifies both child subtypes and child forms. Specify one '.\n              'or the other, but not both.',\n              $key));\n        }\n      }\n\n      $fields = idx($value, 'fields');\n      if ($fields) {\n        foreach ($fields as $field_key => $configuration) {\n          PhutilTypeSpec::checkMap(\n            $configuration,\n            array(\n              'disabled' => 'optional bool',\n              'name' => 'optional string',\n            ));\n        }","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php#L188-L224","documentation":"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.","triggerScenarios":"Config such as {\"key\": \"parent\", \"name\": \"Parent\", \"children\": {\"subtypes\": [\"childa\"], \"forms\": [\"task.form.c2\" ]}} — both keys non-empty inside the same children block.","commonSituations":"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\".","solutions":["Keep exactly one of \"subtypes\" or \"forms\" in each children block and delete the other","Prefer \"subtypes\" when the children are ordinary subtypes; use \"forms\" only when you must point at specific form identifiers/markers","After fixing, re-check that referenced child subtype keys still exist in the config"],"exampleFix":"// before\n{\n  \"key\": \"parent\", \"name\": \"Parent\",\n  \"children\": {\n    \"subtypes\": [\"childa\", \"childb\"],\n    \"forms\": [\"task.form.c1\"]\n  }\n}\n\n// after\n{\n  \"key\": \"parent\", \"name\": \"Parent\",\n  \"children\": {\n    \"subtypes\": [\"childa\", \"childb\"]\n  }\n}","handlingStrategy":"validation","validationCode":"foreach ($config as $entry) {\n  $children = idx($entry, 'children');\n  if ($children) {\n    if (!empty($children['subtypes']) && !empty($children['forms'])) {\n      // reject before saving: choose one mechanism only\n    }\n  }\n}","typeGuard":"function childrenBlockExclusive(array $children) {\n  return !( !empty($children['subtypes']) && !empty($children['forms']) );\n}","tryCatchPattern":null,"preventionTips":["Pick 'subtypes' OR 'forms' per parent, never both","When migrating to form-based children, delete the old 'subtypes' entry in the same change","Review children blocks carefully during config merges"],"tags":["phabricator","subtypes","config-validation","mutually-exclusive","php"],"backgroundTag":"config-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}