phacility/phabricator · error · Exception
Task status ("%s") has unrecognized value for "locked" confi
Error message
Task status ("%s") has unrecognized value for "locked" configuration ("%s"). Supported values are: "%s", "%s". What it means
The optional 'locked' field of a maniphest.statuses entry may be boolean true/false, or one of the two string constants ManiphestTaskStatus::LOCKED_COMMENTS or LOCKED_EDITS ('locked-comments', 'locked-edits'). Any other value — a string like 'yes', an integer 1, or null-ish placeholders — throws this Exception listing the status, the bad value, and the two supported strings.
Source
Thrown at src/applications/maniphest/constants/ManiphestTaskStatus.php:315
'mfa' => 'optional bool',
));
}
// Supported values are "comments" or "edits". For backward compatibility,
// "true" is an alias of "comments".
foreach ($config as $key => $value) {
$locked = idx($value, 'locked', false);
if ($locked === true || $locked === false) {
continue;
}
if ($locked === self::LOCKED_EDITS ||
$locked === self::LOCKED_COMMENTS) {
continue;
}
throw new Exception(
pht(
'Task status ("%s") has unrecognized value for "locked" '.
'configuration ("%s"). Supported values are: "%s", "%s".',
$key,
$locked,
self::LOCKED_COMMENTS,
self::LOCKED_EDITS));
}
$special_map = array();
foreach ($config as $key => $value) {
$special = idx($value, 'special');
if (!$special) {
continue;
}
if (isset($special_map[$special])) {
throw new Exception(View on GitHub (pinned to 5720a38cfe)
Solutions
- Use real JSON booleans for simple locking: "locked": true or "locked": false.
- Use the exact strings "locked-comments" or "locked-edits" to disable only comments or only edits on that status.
- Drop the 'locked' key entirely when the status should not be locked (false is the default).
Example fix
// before
'archived' => array('name' => 'Archived', 'locked' => 'true'),
// after
'archived' => array('name' => 'Archived', 'locked' => true),
// or: 'locked' => 'locked-comments' Defensive patterns
Strategy: validation
Validate before calling
function is_valid_locked($v) {
return $v === true || $v === false
|| $v === 'locked-comments' || $v === 'locked-edits';
}
foreach ($statuses as $constant => $spec) {
if (isset($spec['locked']) && !is_valid_locked($spec['locked'])) {
throw new InvalidArgumentException("Bad 'locked' for '$constant'");
}
} Type guard
function is_locked_value($v) { return $v === true || $v === false || $v === 'locked-comments' || $v === 'locked-edits'; } Prevention
- Use unquoted JSON booleans; quoted 'true' is a string and invalid.
- Only the exact strings 'locked-comments'/'locked-edits' are accepted for partial locks.
- Omit 'locked' when no locking is needed.
When it happens
Trigger: A config entry like {"archived": {"name": "Archived", "locked": "true"}} (string 'true' instead of boolean) or {"locked": 1}. The $locked === true/=== false and the two string comparisons all fail, so the Exception fires.
Common situations: Hand-written JSON where booleans were quoted. Scripts generating config from a CSV/spreadsheet where the locked column contains 'yes'/'no' or 1/0. Copying examples from forum posts that predate the string lock modes.
Related errors
- Key "%s" is not a valid status constant. Status constants mu
- Value for key "%s" should be a dictionary.
- Configuration has two statuses both marked with the special
- Status "%s" is marked as default, but it is a closed status.
- Status "%s" is marked as the default status for closing task
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/becb105eb256f6e4.
Report an issue: GitHub.