phacility/phabricator · error · Exception
When moving objects between columns on a board, columns must
Error message
When moving objects between columns on a board, columns must be identified by PHIDs. This transaction uses "%s" to identify a column, but that is not a valid column PHID.
What it means
validateColumnPHID() runs during transaction validation for column moves: every column reference must be a real PHID whose type constant equals PhabricatorProjectColumnPHIDType::TYPECONST (prefix PHID-PCD-). phid_get_type() on the supplied value returned something else, so the editor rejects the transaction before touching the board. Typical wrong values: a numeric column ID, a monogram, or a project PHID.
Source
Thrown at src/applications/maniphest/editor/ManiphestTransactionEditor.php:765
}
$engine->queueAddPosition(
$board_phid,
$column_phid,
$object_phid,
$after_phids,
$before_phids);
$engine->applyPositionUpdates();
}
private function validateColumnPHID($value) {
if (phid_get_type($value) == PhabricatorProjectColumnPHIDType::TYPECONST) {
return;
}
throw new Exception(
pht(
'When moving objects between columns on a board, columns must '.
'be identified by PHIDs. This transaction uses "%s" to identify '.
'a column, but that is not a valid column PHID.',
$value));
}
private function getLockValidationErrors($object, array $xactions) {
$errors = array();
$old_owner = $object->getOwnerPHID();
$old_status = $object->getStatus();
$new_owner = $old_owner;
$new_status = $old_status;
$owner_xaction = null;View on GitHub (pinned to 5720a38cfe)
Solutions
- Use the column's real PHID (starts with PHID-PCD-). Get it from 'project.column.search' (Conduit) or $column->getPHID().
- If you only have a numeric ID, resolve it first: id(new PhabricatorProjectColumnQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(), then use getPHID().
- Check the prefix you are passing: PHID-PROJ- is a project/board, PHID-PCD- is a column - passing the board PHID is the classic mistake.
Example fix
// before: raw numeric column ID
->setNewValue(array('columnPHID' => $column_id));
// after: resolve the ID to a real column PHID
$column = id(new PhabricatorProjectColumnQuery())
->setViewer($viewer)
->withIDs(array($column_id))
->executeOne();
if (!$column) {
throw new Exception('No such column ID '.$column_id);
}
->setNewValue(array('columnPHID' => $column->getPHID())); Defensive patterns
Strategy: type-guard
Validate before calling
foreach ($move_specs as $spec) {
if (!is_column_phid($spec['columnPHID'])) {
throw new InvalidArgumentException(
'columnPHID must be a PHID-PCD-... value, got '.$spec['columnPHID']);
}
} Type guard
function is_column_phid($phid) {
return phid_get_type($phid) === PhabricatorProjectColumnPHIDType::TYPECONST;
} Prevention
- Treat PHIDs as opaque typed tokens - never construct or guess them; always fetch them from the API.
- Client-side, validate the PHID-PCD- prefix before submitting a column edit.
When it happens
Trigger: Calling maniphest.edit (Conduit), the editor directly, or any move spec where 'columnPHID' is not a column PHID - e.g. '12' (raw ID), a board/project PHID (PHID-PROJ-...), or a malformed/hand-typed PHID string. The check is purely type-based; it fires before the existence check in error 880.
Common situations: Scripts migrated from older APIs that identified columns by numeric ID; copy-pasting the board's project PHID instead of the column's PHID; client code constructing PHIDs by string concatenation or guessing the prefix.
Related errors
- Column move transaction specifies column PHID "%s", but ther
- Transaction specifies both "afterPHID" and "afterPHIDs". Spe
- Transaction specifies both "beforePHID" and "beforePHIDs". S
- Invalid '%s' value for PHID transaction. Value should contai
- Edge transactions must have destination PHIDs as in edge lis
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/f83574696ff05c61.
Report an issue: GitHub.