{"record":{"id":"48f0d8240fd949c4","repo":"phacility/phabricator","slug":"order-vector-s-is-invalid-only-the-last-column","errorCode":null,"errorMessage":"Order vector \"%s\" is invalid: only the last column in an order may be unique, but \"%s\" is a unique column and not the last column in the order.","messagePattern":"Order vector \"(.+?)\" is invalid: only the last column in an order may be unique, but \"(.+?)\" is a unique column and not the last column in the order\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php","lineNumber":1085,"sourceCode":"\n    // Make sure that the last column is unique so that this is a strong\n    // ordering which can be used for paging.\n    $last = last($unique);\n    if ($last !== true) {\n      throw new Exception(\n        pht(\n          'Order vector \"%s\" is invalid: the last column in an order must '.\n          'be a column with unique values, but \"%s\" is not unique.',\n          $vector->getAsString(),\n          last_key($unique)));\n    }\n\n    // Make sure that other columns are not unique; an ordering like \"id, name\"\n    // does not make sense because only \"id\" can ever have an effect.\n    array_pop($unique);\n    foreach ($unique as $key => $is_unique) {\n      if ($is_unique) {\n        throw new Exception(\n          pht(\n            'Order vector \"%s\" is invalid: only the last column in an order '.\n            'may be unique, but \"%s\" is a unique column and not the last '.\n            'column in the order.',\n            $vector->getAsString(),\n            $key));\n      }\n    }\n\n    $this->orderVector = $vector;\n    return $this;\n  }\n\n\n  /**\n   * Get the effective order vector.\n   *\n   * @return PhabricatorQueryOrderVector Effective vector.","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php#L1067-L1103","documentation":"Thrown by setOrderVector() when a column marked unique appears anywhere except the last position. The vector is validated left to right and then checked inversely: once ordering is decided by a unique column (e.g. 'id'), any later column can never change the order — 'ORDER BY id, title' is meaningless — so unique columns are only legal as the final tiebreaker.","triggerScenarios":"setOrderVector(array('id', 'title')) — id is unique but not last; putting PHID or any unique-key column before another sort column.","commonSituations":"Developers adding id 'for good measure' at the front of an order; refactors that reorder vector components without noticing id was the terminator.","solutions":["Move the unique column to the end: array('title', 'id') instead of array('id', 'title')","Drop the unique column entirely if the remaining last column is itself unique"],"exampleFix":"// before: unique column first\n$query->setOrderVector(array('id', 'title'));\n\n// after: unique column last\n$query->setOrderVector(array('title', 'id'));","handlingStrategy":"validation","validationCode":"// Enforce: unique columns may only occupy the last position.\n$orderable = $query->getOrderableColumns();\n$vector = array_values($vector);\nforeach ($vector as $i => $key) {\n  $is_unique = idx($orderable[$key], 'unique', false);\n  if ($is_unique && $i !== count($vector) - 1) {\n    unset($vector[$i]); // drop meaningless components after a unique key\n  }\n}\n$query->setOrderVector(array_values($vector));","typeGuard":"function vectorHasUniqueOnlyLast(PhabricatorCursorPagedPolicyAwareQuery $query, array $vector) {\n  $orderable = $query->getOrderableColumns();\n  $last = count($vector) - 1;\n  foreach ($vector as $i => $key) {\n    if (idx($orderable[$key], 'unique', false) && $i !== $last) { return false; }\n  }\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Place 'id' last in order vectors, never first","Remember columns after a unique column can never affect the ordering — drop them"],"tags":["query","sorting","order-vector","pagination","phabricator"],"backgroundTag":"invalid-order-vector","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}