phacility/phabricator · error · Exception
Edge transactions must have destination PHIDs as in edge lis
Error message
Edge transactions must have destination PHIDs as in edge lists (found key "%s" on transaction of type "%s").
What it means
In an edge delta list, each entry must be keyed by the destination PHID: checkEdgeList() verifies that phid_get_type() on the key returns a real type rather than PHID_TYPE_UNKNOWN. This exception fires when a list contains a key that is not a well-formed PHID.
Source
Thrown at src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php:2677
$xaction,
$edge,
$dst_phid);
}
foreach ($new_rem as $dst_phid => $edge) {
unset($result[$dst_phid]);
}
return $result;
}
private function checkEdgeList($list, $edge_type) {
if (!$list) {
return;
}
foreach ($list as $key => $item) {
if (phid_get_type($key) === PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
throw new Exception(
pht(
'Edge transactions must have destination PHIDs as in edge '.
'lists (found key "%s" on transaction of type "%s").',
$key,
$edge_type));
}
if (!is_array($item) && $item !== $key) {
throw new Exception(
pht(
'Edge transactions must have PHIDs or edge specs as values '.
'(found value "%s" on transaction of type "%s").',
$item,
$edge_type));
}
}
}
private function normalizeEdgeTransactionValue(View on GitHub (pinned to 5720a38cfe)
Solutions
- Resolve identifiers to PHIDs before building the transaction (e.g. PhabricatorObjectQuery with monograms, or the appropriate search endpoint).
- Key every edge entry by its destination PHID: array('+' => array('PHID-PROJ-...' => 'PHID-PROJ-...')).
- Sanitize/trim values when importing external data and log any token that does not start with 'PHID-'.
Example fix
// before
$new = array('+' => array('alice' => 'alice'));
// after
$user_phid = id(new PhabricatorPeopleUserFindEngine())
->setViewer($viewer)
->findUsers('alice'); // then use resolved PHID(s)
$new = array('+' => array($user_phid => $user_phid)); Defensive patterns
Strategy: validation
Validate before calling
// Resolve every identifier to a PHID before building the edge list
$phids = array();
foreach ($raw_identifiers as $identifier) {
$phid = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withNames(array($identifier))
->executeOne();
if (!$phid) {
continue; // or collect an error for the user
}
$phids[] = $phid->getPHID();
}
$new = array('+' => array_fuse($phids)); Type guard
function isPhid($value) {
return is_string($value)
&& preg_match('/^PHID-[A-Z]{4}-/', $value)
&& phid_get_type($value) !== PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
} Prevention
- Always resolve monograms/usernames to PHIDs before constructing transactions.
- Reject or trim any token that does not start with 'PHID-' at the input boundary.
- When importing external data, validate PHIDs in a pre-pass and log rejects instead of submitting them.
When it happens
Trigger: Passing an edge list keyed by usernames, monograms (e.g. #project), raw IDs, or malformed PHID strings (typo, truncation, whitespace) inside '+'/'-'/'=' values of a TYPE_EDGE transaction.
Common situations: Script converts user input like 'alice' or 'T123' directly into edge-list keys without resolving them to PHIDs first; data imported from an external system contains non-PHID identifiers; a PHID got mangled during transport or string concatenation.
Related errors
- Invalid '%s' value for PHID transaction. Value should contai
- Invalid '%s' value for Edge transaction. Value should contai
- Edge transactions must have PHIDs or edge specs as values (f
- Transaction edge data must either be the edge PHID or an edg
- Edge transaction includes edge of type '%s', but transaction
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/32cf52b633aceda0.
Report an issue: GitHub.