phacility/phabricator · error · Exception
Storage patch "%s" specifies a "@phase" value ("%s"), but th
Error message
Storage patch "%s" specifies a "@phase" value ("%s"), but this is not a recognized phase. Valid phases are: %s. What it means
The '@phase' attribute in a PHP patch's header comment must name a recognized phase from PhabricatorStoragePatch::getPhaseList() (currently 'default' and 'worker'). An unrecognized value means ordering cannot be validated, so the loader rejects the patch file.
Source
Thrown at src/infrastructure/storage/patch/PhabricatorSQLPatchList.php:301
if (preg_match('(^\s*//\s*@(\S+)(?:\s+(.*))?\z)', $line, $matches)) {
$attr_key = $matches[1];
$attr_value = trim(idx($matches, 2));
switch ($attr_key) {
case 'phase':
$phase_name = $attr_value;
if (!strlen($phase_name)) {
throw new Exception(
pht(
'Storage patch "%s" specifies a "@phase" attribute with '.
'no phase value. Phase attributes must specify a value, '.
'like "@phase default".',
$patch_name));
}
if (!isset($phase_map[$phase_name])) {
throw new Exception(
pht(
'Storage patch "%s" specifies a "@phase" value ("%s"), '.
'but this is not a recognized phase. Valid phases '.
'are: %s.',
$patch_name,
$phase_name,
implode(', ', $phase_list)));
}
if (isset($attributes['phase'])) {
throw new Exception(
pht(
'Storage patch "%s" specifies a "@phase" value ("%s"), '.
'but it already has a specified phase ("%s"). Patches '.
'may not specify multiple phases.',
$patch_name,
$phase_name,
$attributes['phase']));View on GitHub (pinned to 5720a38cfe)
Solutions
- Change the value to 'default' or 'worker' as listed in the error message.
- If you did not mean to phase the patch, remove the '@phase' line.
- Re-run 'bin/storage status' to confirm the file parses.
Example fix
// before (top of patch file) // @phase daemon // after // @phase worker
Defensive patterns
Strategy: validation
Validate before calling
$valid = array_fuse(PhabricatorStoragePatch::getPhaseList());
// before writing '// @phase X' in a patch header:
if (!isset($valid['worker'])) { /* pick from: ' . implode(', ', array_keys($valid)) . ') */ }
// i.e. only ever write '// @phase default' or '// @phase worker' Prevention
- Copy a working '@phase worker' line from an existing patch rather than typing the literal.
- Treat the phase list as fixed ('default', 'worker'); do not invent phases.
When it happens
Trigger: A patch file header says '// @phase setup', '// @phase daemon', '// @phase Default', or any value other than exactly 'default' or 'worker'. Case and whitespace matter — the value is matched literally against the phase map.
Common situations: Guessing phase names; copying an annotation from a different Phabricator version whose phase list differed; capitalization or trailing-punctuation typos.
Related errors
- Storage patch "%s" specifies a "@phase" attribute with no ph
- Storage patch "%s" specifies a "@phase" value ("%s"), but it
- Storage patch "%s" specifies it should apply in phase "%s",
- Storage patch "%s" executes in phase "%s", but depends on pa
- Storage patch "%s" specifies attribute "%s", but this attrib
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/2dd46f3877b01276.
Report an issue: GitHub.