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

  1. Change the value to 'default' or 'worker' as listed in the error message.
  2. If you did not mean to phase the patch, remove the '@phase' line.
  3. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/2dd46f3877b01276. Report an issue: GitHub.