{"id":"033b57a2a8b6a380","repo":"redis/redis-py","slug":"did-not-receive-a-sortbyfield","errorCode":null,"errorMessage":"Did not receive a SortByField.","messagePattern":"Did not receive a SortByField\\.","errorType":"validation","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"redis/commands/search/query.py","lineNumber":237,"sourceCode":"        if self._with_scores:\n            args.append(\"WITHSCORES\")\n        if self._ids:\n            args.append(\"INKEYS\")\n            args.append(len(self._ids))\n            args += self._ids\n        if self._slop >= 0:\n            args += [\"SLOP\", self._slop]\n        if self._timeout is not None:\n            args += [\"TIMEOUT\", self._timeout]\n        if self._in_order:\n            args.append(\"INORDER\")\n        if self._return_fields:\n            args.append(\"RETURN\")\n            args.append(len(self._return_fields))\n            args += self._return_fields\n        if self._sortby:\n            if not isinstance(self._sortby, SortbyField):\n                raise AttributeError(\"Did not receive a SortByField.\")\n            args.append(\"SORTBY\")\n            args += self._sortby.args\n        if self._language:\n            args += [\"LANGUAGE\", self._language]\n        if self._expander:\n            args += [\"EXPANDER\", self._expander]\n        if self._dialect:\n            args += [\"DIALECT\", self._dialect]\n\n        return args\n\n    def paging(self, offset: int, num: int) -> \"Query\":\n        \"\"\"\n        Set the paging for the query (defaults to 0..10).\n\n        - **offset**: Paging offset for the results. Defaults to 0\n        - **num**: How many results do we want\n        \"\"\"","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/search/query.py#L219-L255","documentation":"Raised by Query._get_args_tags when the internal _sortby attribute is set but is not a SortbyField instance. The public sort_by() method always constructs a SortbyField, so this error signals that _sortby was assigned directly with a foreign object. It prevents emitting a malformed SORTBY clause.","triggerScenarios":"Directly assigning query._sortby = 'price' or query._sortby = ('price', 'ASC') instead of calling sort_by(); or a third-party wrapper overwriting the attribute.","commonSituations":"Attempting to set sort via attribute assignment; deserializing a query config into attributes; copying fields between Query objects without type checks.","solutions":["Use the setter: query.sort_by('price', asc=True).","If constructing a SortbyField manually, assign it via sort_by or ensure the object is redis.commands.search.query.SortbyField.","Do not write to query._sortby directly."],"exampleFix":"// before\nquery._sortby = 'price'\n// after\nquery.sort_by('price', asc=True)","handlingStrategy":"validation","validationCode":"from redis.commands.search.query import SortbyField\n\ndef set_sort(query, field, asc=True):\n    sb = SortbyField(field, asc) if not isinstance(field, SortbyField) else field\n    query._sortby = sb  # or prefer query.sort_by(field, asc)","typeGuard":"from redis.commands.search.query import SortbyField\n\ndef is_sortbyfield(val) -> bool:\n    return val is None or isinstance(val, SortbyField)","tryCatchPattern":"try:\n    query.get_args()\nexcept AttributeError:\n    query.sort_by('price', asc=True)","preventionTips":["Always set sort order via query.sort_by(), never by attribute assignment.","If copying query state, reconstruct SortbyField instances rather than aliasing.","Avoid exposing _sortby in wrappers."],"tags":["search","search-and-query","query","sort","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}