phacility/phabricator · error · Exception

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

Error message

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

What it means

PHID-list transactions (subscribers, project members, etc.) encode their new value as a delta dictionary whose only legal keys are '+' (add PHIDs), '-' (remove PHIDs) and '=' (set the full list). getPHIDList() strips those three keys and throws if anything else remains in the 'new' value.

Source

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

      $old = array_fuse($xaction->getOldValue());
    }

    return $this->getPHIDList($old, $xaction->getNewValue());
  }

  public function getPHIDList(array $old, array $new) {
    $new_add = idx($new, '+', array());
    unset($new['+']);
    $new_rem = idx($new, '-', array());
    unset($new['-']);
    $new_set = idx($new, '=', null);
    if ($new_set !== null) {
      $new_set = array_fuse($new_set);
    }
    unset($new['=']);

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

    $result = array();

    foreach ($old as $phid) {
      if ($new_set !== null && empty($new_set[$phid])) {
        continue;
      }
      $result[$phid] = $phid;
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Wrap the value in one of the three delta keys: setNewValue(array('=' => $phids)) to replace the list, array('+' => $phids) to add, array('-' => $phids) to remove.
  2. When submitting via Conduit, send value as {"=": ["PHID-..."]} rather than a bare list.
  3. Audit custom transaction types for any setNewValue() call whose argument is not keyed by exactly +, -, or =.

Example fix

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

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

Strategy: type-guard

Validate before calling

// Build a legal PHID delta instead of trusting caller input
function phid_delta(array $set = null, array $add = array(), array $rem = array()) {
  if ($set !== null) {
    return array('=' => array_values($set));
  }
  $delta = array();
  if ($add) { $delta['+'] = array_values($add); }
  if ($rem) { $delta['-'] = array_values($rem); }
  return $delta;
}

Type guard

function isPhidDeltaValue($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 PHID transaction/', $ex->getMessage())) {
    // Log the offending keys: implode(',', array_keys($bad_value))
  }
  throw $ex;
}

Prevention

When it happens

Trigger: Building a transaction with ->setNewValue(array($phid)) or setNewValue(array('add' => ..., 0 => ...)) instead of array('=' => array($phid)); any typo key like 'plus', or a numerically-indexed flat PHID list, leaves leftover keys after +,-,= are removed and triggers the exception inside applyTransactions().

Common situations: Custom code or Conduit scripts passing a raw list of PHIDs instead of a delta dict; mixing up the wire format between edge transactions and PHID transactions; copy-pasting an old pre-delta API call.

Related errors


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