phacility/phabricator · error · Exception

%s '%s' has a patch '%s' which is not an array.

Error message

%s '%s' has a patch '%s' which is not an array.

What it means

While merging all patch lists, a key in some PhabricatorSQLPatchList subclass's getPatches() maps to a non-array value. Every patch definition must be an array with at least `type` and `name` keys; this exception means a patch was defined as a scalar, so the patch list code itself is broken — almost always by hand editing or a bad merge.

Source

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

      ->setUniqueMethod('getNamespace')
      ->execute();

    $specs = array();
    $seen_namespaces = array();

    $phases = PhabricatorStoragePatch::getPhaseList();
    $phases = array_fuse($phases);

    $default_phase = PhabricatorStoragePatch::getDefaultPhase();

    foreach ($patch_lists as $patch_list) {
      $last_keys = array_fill_keys(
        array_keys($phases),
        null);

      foreach ($patch_list->getPatches() as $key => $patch) {
        if (!is_array($patch)) {
          throw new Exception(
            pht(
              "%s '%s' has a patch '%s' which is not an array.",
              __CLASS__,
              get_class($patch_list),
              $key));
        }

        $valid = array(
          'type'    => true,
          'name'    => true,
          'after'   => true,
          'legacy'  => true,
          'dead'    => true,
          'phase' => true,
        );

        foreach ($patch as $pkey => $pval) {
          if (empty($valid[$pkey])) {

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Open the class named in the message and turn the flagged value into an array with `type` and `name` keys.
  2. Copy the exact structure of neighbouring patches in the same file (valid types are db, sql, php).
  3. Run `php -l` on the file and check for merge-conflict residue if it was recently merged.

Example fix

// before
'my.change' => 'my_change.sql',

// after
'my.change' => array(
  'type' => 'sql',
  'name' => 'my_change.sql',
),
Defensive patterns

Strategy: validation

Validate before calling

foreach ($patch_list->getPatches() as $key => $patch) {
  if (!is_array($patch)) {
    throw new InvalidArgumentException('patch '.$key.' must be an array');
  }
}

Type guard

function isPatchDefinition($patch) {
  return is_array($patch) && isset($patch['type'], $patch['name']);
}

Prevention

When it happens

Trigger: A getPatches() entry like 'my.change' => 'my_change.sql' (a plain string) instead of an array; the exception names the offending class and key.

Common situations: Writing a first custom patch and returning a filename string; merge conflicts in patch list files resolved incorrectly; copying an outdated patch-definition format from old documentation.

Related errors


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