phacility/phabricator · error · Exception
Subtype configuration is invalid: it must be a list of subty
Error message
Subtype configuration is invalid: it must be a list of subtype specifications.
What it means
PhabricatorEditEngineSubtype::validateConfiguration() starts by requiring the subtype configuration value itself to be a PHP list (array of subtype specification dictionaries). This exception fires when the config is not an array at all — a string, map, or scalar — i.e. the whole shape is wrong before any individual subtype is inspected.
Source
Thrown at src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php:150
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(
$value,
array(
'key' => 'string',
'name' => 'string',
'tag' => 'optional string',
'color' => 'optional string',
'icon' => 'optional string',
'children' => 'optional map<string, wild>',
'fields' => 'optional map<string, wild>',
'mutations' => 'optional list<string>',View on GitHub (pinned to 5720a38cfe)
Solutions
- Make the top-level value a JSON list of dictionaries, each carrying its own "key" field
- Start from the documented example config (a list containing at least the "default" subtype) and extend it
- Re-save through the config editor and re-read the stored value to confirm it is a list
Example fix
// before
{
"bug": { "name": "Bug" },
"feature": { "name": "Feature" }
}
// Exception: Subtype configuration is invalid: it must be a list ...
// after
[
{ "key": "default", "name": "Default" },
{ "key": "bug", "name": "Bug" },
{ "key": "feature", "name": "Feature" }
] Defensive patterns
Strategy: validation
Validate before calling
if (!is_array($config) || $config !== array_values($config)) {
// reject before saving: config must be a LIST of subtype dicts
} Type guard
function isSubtypeConfigList($config) {
return is_array($config)
&& $config === array_values($config)
&& array_filter($config, 'is_array') === $config;
} Prevention
- Start from the documented example list and extend, rather than authoring JSON from scratch
- Each entry carries its own "key"; never key the top level by subtype
- Re-read the saved config after writing to confirm the stored shape is a list
When it happens
Trigger: Setting maniphest.subtypes (or the engine's subtype config) to a JSON object keyed by subtype ({"bug": {...}}), a string, or leaving a placeholder scalar instead of a JSON list [{...}, {...}].
Common situations: Hand-editing raw config JSON and using a map because it reads nicer; pasting YAML-style mappings; misunderstanding that the container must be a list with 'key' inside each entry.
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
- Subtype "%s" is not valid: subtype keys must be no longer th
- Subtype "%s" is not valid: subtype keys must have a minimum
- Subtype "%s" is not valid: subtype keys may only contain low
- Subtype configuration is invalid: two subtypes use the same
- Subtype configuration is invalid: subtype with key "%s" has
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/d5970006e6267400.
Report an issue: GitHub.