phacility/phabricator · error · Exception
Two different task priorities ("%s" and "%s") have the same
Error message
Two different task priorities ("%s" and "%s") have the same keyword ("%s"). Keywords must uniquely identify priorities. What it means
Priority keywords must uniquely identify a priority across the whole maniphest.priorities map. The validator accumulates every keyword in $all_keywords keyed by keyword -> priority name; when a later level reuses a keyword already claimed by a different priority, it throws with (new name, previous name, keyword). This matters because mail/Places commands like '!priority high' resolve by keyword alone.
Source
Thrown at src/applications/maniphest/constants/ManiphestTaskPriority.php:247
'disabled' => 'optional bool',
));
$keywords = $value['keywords'];
foreach ($keywords as $keyword) {
if (!self::isValidPriorityKeyword($keyword)) {
throw new Exception(
pht(
'Key "%s" is not a valid priority keyword. Priority keywords '.
'must be 1-64 alphanumeric characters and cannot be '.
'exclusively digits. For example, "%s" or "%s" are '.
'reasonable choices.',
$keyword,
'low',
'critical'));
}
if (isset($all_keywords[$keyword])) {
throw new Exception(
pht(
'Two different task priorities ("%s" and "%s") have the same '.
'keyword ("%s"). Keywords must uniquely identify priorities.',
$value['name'],
$all_keywords[$keyword],
$keyword));
}
$all_keywords[$keyword] = $value['name'];
}
}
}
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Give each level disjoint keywords, e.g. 'high' and 'higher'/'unbreak-now', never the same token twice.
- After editing, scan the config for duplicate keywords programmatically before saving.
- If a keyword genuinely must move to another level, delete it from the old level's list in the same edit.
Example fix
// before
'90' => array('name' => 'High', 'keywords' => array('high')),
'80' => array('name' => 'Very High', 'keywords' => array('high', 'urgent')),
// after
'90' => array('name' => 'High', 'keywords' => array('high')),
'80' => array('name' => 'Very High', 'keywords' => array('very-high', 'urgent'))) Defensive patterns
Strategy: validation
Validate before calling
$seen = array();
foreach ($priorities as $const => $spec) {
foreach ($spec['keywords'] as $kw) {
if (isset($seen[$kw])) {
throw new InvalidArgumentException("Keyword '$kw' used by both {$seen[$kw]} and {$spec['name']}");
}
$seen[$kw] = $spec['name'];
}
} Prevention
- Run a duplicate-keyword scan over the config before every save.
- When moving a keyword between levels, remove it from the old list in the same edit.
- Prefer distinct prefixed slugs when merging priority schemes.
When it happens
Trigger: Two levels both listing 'high': {"90": {"name": "High", "keywords": ["high"]}, "80": {"name": "Very High", "keywords": ["high", "urgent"]}}. The second occurrence triggers the exception.
Common situations: Merging two priority configs (e.g. after a team merger) where both defined 'high'. Copy-pasting a level and editing the name but forgetting the keywords list. Renaming a priority but keeping the old keyword on the new one.
Related errors
- Configuration is not valid. Maniphest priority configuration
- Key "%s" is not a valid priority constant. Priority constant
- Value for key "%s" should be a dictionary.
- Key "%s" is not a valid priority keyword. Priority keywords
- Configuration is not valid. Maniphest points configuration m
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/c8214404b792153a.
Report an issue: GitHub.