phacility/phabricator · error · Exception

Invalid '%s' value for Edge transaction. Value should contai

Error message

Invalid '%s' value for Edge transaction. Value should contain only keys '%s' (add edges), '%s' (remove edges) and '%s' (set edges).

What it means

Edge transactions (projects, revert-to, dependencies, etc.) encode their new value as a delta dictionary keyed by '+' (add edges), '-' (remove edges) and '=' (set edges). getEdgeTransactionNewValue() removes those keys and throws if the 'new' value still contains any other key.

Source

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

      unset($result[$phid]);
    }

    return array_values($result);
  }

  protected function getEdgeTransactionNewValue(
    PhabricatorApplicationTransaction $xaction) {

    $new = $xaction->getNewValue();
    $new_add = idx($new, '+', array());
    unset($new['+']);
    $new_rem = idx($new, '-', array());
    unset($new['-']);
    $new_set = idx($new, '=', null);
    unset($new['=']);

    if ($new) {
      throw new Exception(
        pht(
          "Invalid '%s' value for Edge transaction. Value should contain only ".
          "keys '%s' (add edges), '%s' (remove edges) and '%s' (set edges).",
          'new',
          '+',
          '-',
          '='));
    }

    $old = $xaction->getOldValue();

    $lists = array($new_set, $new_add, $new_rem);
    foreach ($lists as $list) {
      $this->checkEdgeList($list, $xaction->getMetadataValue('edge:type'));
    }

    $result = array();
    foreach ($old as $dst_phid => $edge) {

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Use only '+'/'-'/'=' keys: setNewValue(array('+' => array($dst_phid => $dst_phid))) to add, array('-' => ...) to remove, array('=' => ...) to set.
  2. When calling Conduit, format edge values as {"+": [...]} / {"-": [...]} / {"=": [...]}.
  3. Check the specific transaction type's expected shape in its getTransactionType() implementation if unsure.

Example fix

// before
$xaction->setNewValue(array($project_phid));

// after
$xaction->setNewValue(array('+' => array($project_phid => $project_phid)));
Defensive patterns

Strategy: type-guard

Validate before calling

// Normalize an arbitrary edge payload into a legal delta
function edge_delta(array $set = null, array $add = array(), array $rem = array()) {
  if ($set !== null) {
    return array('=' => array_fuse($set));
  }
  $delta = array();
  if ($add) { $delta['+'] = array_fuse($add); }
  if ($rem) { $delta['-'] = array_fuse($rem); }
  return $delta;
}

Type guard

function isEdgeDeltaValue($value) {
  if (!is_array($value)) {
    return false;
  }
  foreach ($value as $key => $ignored) {
    if (!in_array($key, array('+', '-', '='), true)) {
      return false;
    }
  }
  return true;
}

Try / catch

try {
  $editor->applyTransactions($object, $xactions);
} catch (Exception $ex) {
  if (preg_match('/Invalid \'new\' value for Edge transaction/', $ex->getMessage())) {
    // Reformat value as a +/-/= delta and retry once
  }
  throw $ex;
}

Prevention

When it happens

Trigger: Setting an edge transaction's new value to a flat array of PHIDs, a dict keyed by PHIDs, or with keys like 'add'/'remove' instead of '+'/'-'/'='. The throw happens while the editor applies the transaction, after value normalization begins.

Common situations: Conduit callers sending {"value": ["PHID-..."]} for project.setprojects-style endpoints; custom code constructing PhabricatorTransactions::TYPE_EDGE with setNewValue(array($dst_phid)); confusion because '=' here takes a list-or-dict of edges, not the same shape as PHID list transactions.

Related errors


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