phacility/phabricator · error · Exception
Status "%s" is marked as the status for closing tasks as dup
Error message
Status "%s" is marked as the status for closing tasks as duplicates, but it is not a closed status. It should be a closed status.
What it means
A status marked "special": "duplicate" is the status applied when a task is closed as a duplicate, and it must be a closed status. The validator's SPECIAL_DUPLICATE case throws when that entry lacks "closed": true, since merge/duplicate handling assumes the target status closes the task.
Source
Thrown at src/applications/maniphest/constants/ManiphestTaskStatus.php:364
pht(
'Status "%s" is marked as default, but it is a closed '.
'status. The default status should be an open status.',
$key));
}
break;
case self::SPECIAL_CLOSED:
if (empty($value['closed'])) {
throw new Exception(
pht(
'Status "%s" is marked as the default status for closing '.
'tasks, but is not a closed status. It should be a closed '.
'status.',
$key));
}
break;
case self::SPECIAL_DUPLICATE:
if (empty($value['closed'])) {
throw new Exception(
pht(
'Status "%s" is marked as the status for closing tasks as '.
'duplicates, but it is not a closed status. It should '.
'be a closed status.',
$key));
}
break;
}
$special_map[$special] = $key;
}
// NOTE: We're not explicitly validating that we have at least one open
// and one closed status, because the DEFAULT and CLOSED specials imply
// that to be true. If those change in the future, that might become a
// reasonable thing to validate.
$required = array(View on GitHub (pinned to 5720a38cfe)
Solutions
- Set "closed": true on the status that carries "special": "duplicate".
- Model your duplicate status on the shipped one: {"duplicate": {"name": "Duplicate", "closed": true, "special": "duplicate", ...}}.
- After any status edit, verify the three special statuses (default/closed/duplicate) all satisfy their open/closed requirements.
Example fix
// before
'duplicate' => array('name' => 'Duplicate', 'special' => 'duplicate'),
// after
'duplicate' => array('name' => 'Duplicate', 'closed' => true, 'special' => 'duplicate'), Defensive patterns
Strategy: validation
Validate before calling
foreach ($statuses as $constant => $spec) {
if (idx($spec, 'special') === 'duplicate' && empty($spec['closed'])) {
throw new InvalidArgumentException("Duplicate status '$constant' must set closed: true");
}
} Prevention
- The 'special': 'duplicate' status must include "closed": true.
- Do not batch-remove 'closed' flags without checking special roles.
- Keep the shipped duplicate entry as the template.
When it happens
Trigger: maniphest.statuses entry like {"duplicate": {"name": "Duplicate", "special": "duplicate"}} without "closed": true — typically after renaming or hand-rebuilding the status list.
Common situations: Customizing statuses and rewriting the duplicate entry from an open-status template. Removing 'closed' from several statuses in a batch edit and accidentally including the duplicate one.
Related errors
- Status "%s" is marked as default, but it is a closed status.
- Status "%s" is marked as the default status for closing task
- Configuration has two statuses both marked with the special
- Key "%s" is not a valid status constant. Status constants mu
- Value for key "%s" should be a dictionary.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/1c7236bc348ed380.
Report an issue: GitHub.