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

  1. Use the column's real PHID (starts with PHID-PCD-). Get it from 'project.column.search' (Conduit) or $column->getPHID().
  2. If you only have a numeric ID, resolve it first: id(new PhabricatorProjectColumnQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(), then use getPHID().
  3. 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

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


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