phacility/phabricator · error · Exception
Status "%s" is marked as the default status for closing task
Error message
Status "%s" is marked as the default status for closing tasks, but is not a closed status. It should be a closed status.
What it means
A status marked "special": "closed" is the status tasks move to on normal close, so it must itself be a closed status. The validator's SPECIAL_CLOSED case throws when that entry lacks "closed": true, because closing a task into an open status would corrupt open/closed semantics (burn-down, board behavior).
Source
Thrown at src/applications/maniphest/constants/ManiphestTaskStatus.php:354
'attribute "%s" ("%s" and "%s"). There should be only one.',
$special,
$special_map[$special],
$key));
}
switch ($special) {
case self::SPECIAL_DEFAULT:
if (!empty($value['closed'])) {
throw new Exception(
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;
}View on GitHub (pinned to 5720a38cfe)
Solutions
- Add "closed": true to whichever status carries "special": "closed".
- Keep the canonical pattern: close-target statuses (resolved, invalid, wontfix) all set "closed": true; only the special one is REQUIRED to.
- Diff your custom statuses against the shipped defaults to confirm every special status has matching closed-ness.
Example fix
// before
'resolved' => array('name' => 'Resolved', 'special' => 'closed'),
// after
'resolved' => array('name' => 'Resolved', 'closed' => true, 'special' => 'closed'), Defensive patterns
Strategy: validation
Validate before calling
foreach ($statuses as $constant => $spec) {
if (idx($spec, 'special') === 'closed' && empty($spec['closed'])) {
throw new InvalidArgumentException("Close-default status '$constant' must set closed: true");
}
} Prevention
- The 'special': 'closed' status must include "closed": true.
- Rewrite whole entries carefully so the closed flag survives renames.
- Check all three special statuses after each status config change.
When it happens
Trigger: maniphest.statuses entry like {"resolved": {"name": "Resolved", "special": "closed"}} with no "closed": true — renaming or rebuilding statuses and dropping the closed flag from the close-target.
Common situations: Editing display names by rewriting whole entries and omitting the closed flag. Introducing a custom 'Completed' close status copied from an open status template but keeping the special role.
Related errors
- Status "%s" is marked as default, but it is a closed status.
- Status "%s" is marked as the status for closing tasks as dup
- 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/99f4c29c0c8fbf77.
Report an issue: GitHub.