{"record":{"id":"53e90629f3435453","repo":"phacility/phabricator","slug":"invalid-s-value-for-phid-transaction-value-sho","errorCode":null,"errorMessage":"Invalid '%s' value for PHID transaction. Value should contain only keys '%s' (add PHIDs), '%s' (remove PHIDs) and '%s' (set PHIDS).","messagePattern":"Invalid '(.+?)' value for PHID transaction\\. Value should contain only keys '(.+?)' \\(add PHIDs\\), '(.+?)' \\(remove PHIDs\\) and '(.+?)' \\(set PHIDS\\)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php","lineNumber":2572,"sourceCode":"      $old = array_fuse($xaction->getOldValue());\n    }\n\n    return $this->getPHIDList($old, $xaction->getNewValue());\n  }\n\n  public function getPHIDList(array $old, array $new) {\n    $new_add = idx($new, '+', array());\n    unset($new['+']);\n    $new_rem = idx($new, '-', array());\n    unset($new['-']);\n    $new_set = idx($new, '=', null);\n    if ($new_set !== null) {\n      $new_set = array_fuse($new_set);\n    }\n    unset($new['=']);\n\n    if ($new) {\n      throw new Exception(\n        pht(\n          \"Invalid '%s' value for PHID transaction. Value should contain only \".\n          \"keys '%s' (add PHIDs), '%s' (remove PHIDs) and '%s' (set PHIDS).\",\n          'new',\n          '+',\n          '-',\n          '='));\n    }\n\n    $result = array();\n\n    foreach ($old as $phid) {\n      if ($new_set !== null && empty($new_set[$phid])) {\n        continue;\n      }\n      $result[$phid] = $phid;\n    }\n","sourceCodeStart":2554,"sourceCodeEnd":2590,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php#L2554-L2590","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["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.","When submitting via Conduit, send value as {\"=\": [\"PHID-...\"]} rather than a bare list.","Audit custom transaction types for any setNewValue() call whose argument is not keyed by exactly +, -, or =."],"exampleFix":"// before\n$xaction->setNewValue(array($subscriber_phid));\n\n// after\n$xaction->setNewValue(array('=' => array($subscriber_phid)));","handlingStrategy":"type-guard","validationCode":"// Build a legal PHID delta instead of trusting caller input\nfunction phid_delta(array $set = null, array $add = array(), array $rem = array()) {\n  if ($set !== null) {\n    return array('=' => array_values($set));\n  }\n  $delta = array();\n  if ($add) { $delta['+'] = array_values($add); }\n  if ($rem) { $delta['-'] = array_values($rem); }\n  return $delta;\n}","typeGuard":"function isPhidDeltaValue($value) {\n  if (!is_array($value)) {\n    return false;\n  }\n  foreach ($value as $key => $ignored) {\n    if (!in_array($key, array('+', '-', '='), true)) {\n      return false;\n    }\n  }\n  return true;\n}","tryCatchPattern":"try {\n  $editor->applyTransactions($object, $xactions);\n} catch (Exception $ex) {\n  if (preg_match('/Invalid \\'new\\' value for PHID transaction/', $ex->getMessage())) {\n    // Log the offending keys: implode(',', array_keys($bad_value))\n  }\n  throw $ex;\n}","preventionTips":["Never pass a flat PHID array to setNewValue(); always wrap it in '='/'+'/'-'.","Centralize transaction construction in one helper that emits only delta dicts.","For Conduit clients, run payloads through a schema check that whitelists +,-,= keys."],"tags":["phabricator","transactions","phid","validation","php"],"backgroundTag":"transaction-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}