phacility/phabricator · error · Exception

Transaction edge specification contains unexpected key "%s".

Error message

Transaction edge specification contains unexpected key "%s".

What it means

An edge specification dictionary may only contain the internal edge columns: src, dst, type, data, dateCreated, dateModified, seq and dataID. normalizeEdgeTransactionValue() rejects any other key with this exception.

Source

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

          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:
            throw new Exception(
              pht(
                'Transaction edge specification contains unexpected key "%s".',
                $key));
        }
      }
    }

    $edge['dst'] = $dst_phid;

    $edge_type = $xaction->getMetadataValue('edge:type');
    if (empty($edge['type'])) {
      $edge['type'] = $edge_type;
    } else {
      if ($edge['type'] != $edge_type) {
        $this_type = $edge['type'];
        throw new Exception(
          pht(
            "Edge transaction includes edge of type '%s', but ".

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Move custom payload inside the 'data' key: array('dst' => $phid, 'data' => array('priority' => 3)).
  2. Otherwise restrict the spec to the whitelisted keys and drop the extra field.
  3. If the field must live on the edge itself, extend the edge schema rather than the transaction spec.

Example fix

// before
$edge = array('dst' => $phid, 'priority' => 3);

// after
$edge = array('dst' => $phid, 'data' => array('priority' => 3));
Defensive patterns

Strategy: validation

Validate before calling

$legal = array(
  'src' => true, 'dst' => true, 'type' => true, 'data' => true,
  'dateCreated' => true, 'dateModified' => true, 'seq' => true,
  'dataID' => true,
);
foreach ($edge as $key => $value) {
  if (empty($legal[$key])) {
    // move unknown keys under 'data' or reject them
    unset($edge[$key]);
    $edge['data'][$key] = $value;
  }
}

Type guard

function isLegalEdgeSpec(array $edge) {
  $legal = array('src', 'dst', 'type', 'data',
    'dateCreated', 'dateModified', 'seq', 'dataID');
  foreach (array_keys($edge) as $key) {
    if (!in_array($key, $legal, true)) {
      return false;
    }
  }
  return true;
}

Prevention

When it happens

Trigger: Supplying an edge spec like array('dst' => $phid, 'priority' => 3) where 'priority' is not one of the whitelisted keys; typically from custom code trying to attach arbitrary metadata to an edge via the transaction value instead of the nested 'data' key.

Common situations: Developers assume edge specs accept free-form fields; porting code from a direct EdgeEditor API that tolerated extra keys; generated specs copying a full edge row plus extra computed fields.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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