phacility/phabricator · error · Exception

Storage patch "%s" specifies attribute "%s", but this attrib

Error message

Storage patch "%s" specifies attribute "%s", but this attribute is unknown.

What it means

Inside a PHP patch's header comment block, any line of the form '// @word ...' is parsed as a structured attribute, and the only supported attribute is '@phase'. Anything else ('@group', '@author', '@note', '@TODO') reaches the switch's default case and is rejected, because unknown attributes would silently affect nothing.

Source

Thrown at src/infrastructure/storage/patch/PhabricatorSQLPatchList.php:325

                    $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']));
              }

              $attributes[$attr_key] = $phase_name;
              break;
            default:
              throw new Exception(
                pht(
                  'Storage patch "%s" specifies attribute "%s", but this '.
                  'attribute is unknown.',
                  $patch_name,
                  $attr_key));
          }
        }
        continue;
      }

      // If this is anything else, we're all done. Attributes must be marked
      // in the header of the file.
      break;
    }


    return $attributes;
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Remove the '@' sigil from the offending line (write '// Author: ...' or '// TODO ...' instead of '// @author ...').
  2. Keep structured '@' attributes out of the header block entirely unless it is a valid '// @phase value' line.
  3. Re-run 'bin/storage status' to confirm the file parses.

Example fix

// before (top of patch file)
<?php
// @author adrin
// @phase worker

// after
<?php
// Author: adrin
// @phase worker
Defensive patterns

Strategy: validation

Validate before calling

// Only '@phase' is a legal header attribute; reject any other '@word' line:
foreach (file($patch_path) as $line) {
  if (!preg_match('(^^\s*//)', $line)) { break; } // header block ended
  if (preg_match('^\s*//\s*@(\S+)^', $line, $m) && $m[1] !== 'phase') {
    throw new Exception("Unknown header attribute '@{$m[1]}' in {$patch_path}");
  }
}

Prevention

When it happens

Trigger: The leading '//' comment block of a .php patch starts a line with '@' followed by a word — e.g. '// @group storage' or '// @author someone' — while still inside the header (before any non-comment line). The '@x' shape is reserved; the parser treats it as an attribute, not a comment.

Common situations: Copying phpdoc-style '@author'/'@group' tags from regular source files into a migration header; annotating patch files the way old Phabricator source was annotated; adding '// @TODO' notes at the top of the file.

Related errors


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