phacility/phabricator · error · Exception

Edge transactions must have destination PHIDs as in edge…

Error message

Edge transactions must have destination PHIDs as in edge lists (found key "%s" on transaction of type "%s").

What it means

In an edge delta list, each entry must be keyed by the destination PHID: checkEdgeList() verifies that phid_get_type() on the key returns a real type rather than PHID_TYPE_UNKNOWN. This exception fires when a list contains a key that is not a well-formed PHID.

Solutions

  1. Resolve identifiers to PHIDs before building the transaction (e.g. PhabricatorObjectQuery with monograms, or the appropriate search endpoint).
  2. Key every edge entry by its destination PHID: array('+' => array('PHID-PROJ-...' => 'PHID-PROJ-...')).
  3. Sanitize/trim values when importing external data and log any token that does not start with 'PHID-'.

Example fix

// before
$new = array('+' => array('alice' => 'alice'));

// after
$user_phid = id(new PhabricatorPeopleUserFindEngine())
  ->setViewer($viewer)
  ->findUsers('alice'); // then use resolved PHID(s)
$new = array('+' => array($user_phid => $user_phid));
Defensive patterns

Strategy: validation

Validate before calling

// Resolve every identifier to a PHID before building the edge list
$phids = array();
foreach ($raw_identifiers as $identifier) {
  $phid = id(new PhabricatorObjectQuery())
    ->setViewer($viewer)
    ->withNames(array($identifier))
    ->executeOne();
  if (!$phid) {
    continue; // or collect an error for the user
  }
  $phids[] = $phid->getPHID();
}
$new = array('+' => array_fuse($phids));

Type guard

function isPhid($value) {
  return is_string($value)
    && preg_match('/^PHID-[A-Z]{4}-/', $value)
    && phid_get_type($value) !== PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
}

Prevention

When it happens

Trigger: Passing an edge list keyed by usernames, monograms (e.g. #project), raw IDs, or malformed PHID strings (typo, truncation, whitespace) inside '+'/'-'/'=' values of a TYPE_EDGE transaction.

Common situations: Script converts user input like 'alice' or 'T123' directly into edge-list keys without resolving them to PHIDs first; data imported from an external system contains non-PHID identifiers; a PHID got mangled during transport or string concatenation.

Related errors


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

Appendix: source

Thrown at src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php:2677

        $xaction,
        $edge,
        $dst_phid);
    }

    foreach ($new_rem as $dst_phid => $edge) {
      unset($result[$dst_phid]);
    }

    return $result;
  }

  private function checkEdgeList($list, $edge_type) {
    if (!$list) {
      return;
    }
    foreach ($list as $key => $item) {
      if (phid_get_type($key) === PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
        throw new Exception(
          pht(
            'Edge transactions must have destination PHIDs as in edge '.
            'lists (found key "%s" on transaction of type "%s").',
            $key,
            $edge_type));
      }
      if (!is_array($item) && $item !== $key) {
        throw new Exception(
          pht(
            'Edge transactions must have PHIDs or edge specs as values '.
            '(found value "%s" on transaction of type "%s").',
            $item,
            $edge_type));
      }
    }
  }

  private function normalizeEdgeTransactionValue(

View on GitHub (pinned to 5720a38cfe)