phacility/phabricator · error · Exception

Transaction edge data must either be the edge PHID or an edg

Error message

Transaction edge data must either be the edge PHID or an edge specification dictionary.

What it means

normalizeEdgeTransactionValue() accepts an edge entry that is either the destination PHID as a plain scalar or an array specification. If the entry is a scalar that does not equal the destination PHID it was resolved to, this exception is thrown.

Source

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

      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(
    PhabricatorApplicationTransaction $xaction,
    $edge,
    $dst_phid) {

    if (!is_array($edge)) {
      if ($edge != $dst_phid) {
        throw new Exception(
          pht(
            'Transaction edge data must either be the edge PHID or an edge '.
            'specification dictionary.'));
      }
      $edge = array();
    } else {
      foreach ($edge as $key => $value) {
        switch ($key) {
          case 'src':
          case 'dst':
          case 'type':
          case 'data':
          case 'dateCreated':
          case 'dateModified':
          case 'seq':
          case 'dataID':
            break;
          default:

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Make scalar entries equal their own key: array($dst_phid => $dst_phid).
  2. Put extra per-edge information in an array spec instead of a second PHID string.
  3. Rebuild edge lists with array_fuse() from a single canonical list of destination PHIDs.

Example fix

// before
$edge = $other_phid; // scalar != $dst_phid
$list[$dst_phid] = $edge;

// after
$list[$dst_phid] = $dst_phid;
Defensive patterns

Strategy: validation

Validate before calling

foreach ($edge_list as $dst => $spec) {
  if (!is_array($spec) && $spec !== $dst) {
    throw new Exception(pht('Edge value must equal key %s.', $dst));
  }
}
$xaction->setNewValue(array('=' => $edge_list));

Prevention

When it happens

Trigger: An edge delta list entry whose scalar value points at a different PHID than its key (e.g., a set-list where key => value are two different objects), reaching normalizeEdgeTransactionValue() during transaction application.

Common situations: The same class of bug as the checkEdgeList() guard but arriving through a code path that normalizes values directly (set-lists merged from multiple sources, programmatically generated specs); data from external feeds pairing stale keys with updated values.

Related errors


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