phacility/phabricator · error · Exception

Invalid ' ' value for PHID transaction. Value should…

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.

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.

Appendix: 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)