{"id":"a640721ce5ddec59","repo":"sqlalchemy/sqlalchemy","slug":"at-least-one-order-by-element-is-required","errorCode":null,"errorMessage":"at least one ORDER BY element is required","messagePattern":"at least one ORDER BY element is required","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/sqlalchemy/dialects/postgresql/ext.py","lineNumber":112,"sourceCode":"        self,\n        target: _ColumnExpressionArgument[_T],\n        *order_by: _ColumnExpressionArgument[Any],\n    ): ...\n\n    def __init__(\n        self,\n        target: _ColumnExpressionArgument[_T],\n        *order_by: _ColumnExpressionArgument[Any],\n    ):\n        self.target: ClauseElement = coercions.expect(\n            roles.ExpressionElementRole, target\n        )\n        self.type = self.target.type\n\n        _lob = len(order_by)\n        self.order_by: ClauseElement\n        if _lob == 0:\n            raise TypeError(\"at least one ORDER BY element is required\")\n        elif _lob == 1:\n            self.order_by = coercions.expect(\n                roles.ExpressionElementRole, order_by[0]\n            )\n        else:\n            self.order_by = elements.ClauseList(\n                *order_by, _literal_as_text_role=roles.ExpressionElementRole\n            )\n\n    def self_group(\n        self, against: Optional[OperatorType] = None\n    ) -> ClauseElement:\n        return self\n\n    def get_children(self, **kwargs: Any) -> Iterable[ClauseElement]:\n        return self.target, self.order_by\n\n    def _copy_internals(","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/sqlalchemy/sqlalchemy/blob/d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff/lib/sqlalchemy/dialects/postgresql/ext.py#L94-L130","documentation":"Raised (as TypeError) by the PostgreSQL dialect's aggregate_order_by constructor in ext.py. This helper builds the 'array_agg(x ORDER BY y)' form; the SQL requires at least one ORDER BY expression, so passing zero order_by positional args is invalid.","triggerScenarios":"Calling func.aggregate_order_by(target) or postgresql.ext.aggregate_order_by(target) with only the target column and no following ORDER BY expression. Note: a TypeError is raised here (not ValueError).","commonSituations":"Developers forget the trailing order-by column, dynamically construct the call with *args that expand to nothing, or migrate to the legacy postgresql aggregate_order_by without supplying the ordering column. Modern code should prefer the Core-level func.array_agg(...).aggregate_order_by(...) or just func.array_agg(col) with .within_group().","solutions":["Add at least one ORDER BY expression: aggregate_order_by(func.array_agg(t.c.x), t.c.y.desc()).","Prefer the Core-level dialect-agnostic func aggregate ordering API (Function.aggregate_order_by) instead of the legacy postgresql.ext helper."],"exampleFix":"// before\nfrom sqlalchemy.dialects.postgresql import aggregate_order_by\nstmt = select(func.array_agg(aggregate_order_by(t.c.x)))\n// after\nfrom sqlalchemy.dialects.postgresql import aggregate_order_by\nstmt = select(func.array_agg(aggregate_order_by(t.c.x, t.c.y.desc())))","handlingStrategy":"validation","validationCode":"from sqlalchemy.dialects.postgresql import aggregate_order_by\n\ndef safe_aggregate_order_by(target, *order_by):\n    if len(order_by) == 0:\n        raise TypeError(\"aggregate_order_by requires at least one ORDER BY element\")\n    return aggregate_order_by(target, *order_by)\n\n# e.g. array_agg(col ORDER BY a, b)\nsafe_aggregate_order_by(my_table.c.col, my_table.c.sort_col)","typeGuard":"def has_order_by(*order_by) -> bool:\n    return len(order_by) >= 1 and all(o is not None for o in order_by)","tryCatchPattern":null,"preventionTips":["aggregate_order_by(target, *order_by) is positional; always include at least one order_by column.","If order_by comes from user input, default it (e.g. to an id column) rather than splatting an empty list.","Note this raises TypeError, not ValueError — assert in tests that the call has >=2 positional args."],"tags":["postgresql","aggregate","array-agg","order-by","validation"],"analyzedSha":"d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff","analyzedAt":"2026-08-01T17:20:52.075Z","schemaVersion":2}