{"id":"1a4861e89e6028a9","repo":"redis/redis-py","slug":"did-not-receive-a-filter-object","errorCode":null,"errorMessage":"Did not receive a Filter object.","messagePattern":"Did not receive a Filter object\\.","errorType":"validation","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"redis/commands/search/query.py","lineNumber":213,"sourceCode":"        args += [\"LIMIT\", self._offset, self._num]\n        return args\n\n    def _get_args_tags(self) -> List[Union[str, int, float]]:\n        args: List[Union[str, int, float]] = []\n        if self._no_content:\n            args.append(\"NOCONTENT\")\n        if self._fields:\n            args.append(\"INFIELDS\")\n            args.append(len(self._fields))\n            args += self._fields\n        if self._verbatim:\n            args.append(\"VERBATIM\")\n        if self._no_stopwords:\n            args.append(\"NOSTOPWORDS\")\n        if self._filters:\n            for flt in self._filters:\n                if not isinstance(flt, Filter):\n                    raise AttributeError(\"Did not receive a Filter object.\")\n                args += flt.args\n        if self._with_payloads:\n            args.append(\"WITHPAYLOADS\")\n        if self._scorer:\n            args += [\"SCORER\", self._scorer]\n        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:","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/search/query.py#L195-L231","documentation":"Raised by Query._get_args_tags (invoked via get_args()) when an entry in the query's internal _filters list is not an instance of the Filter base class (NumericFilter or GeoFilter). This guards the query builder from emitting a malformed FILTER/GEOFILTER clause. Normally add_filter() is the only way to populate _filters, so this indicates direct manipulation or a non-Filter object slipped through add_filter.","triggerScenarios":"Calling query.add_filter('price') (passing a field name string instead of a NumericFilter/GeoFilter), or directly assigning query._filters = ['something'], then triggering argument serialization (e.g. via client.ft().search(query)).","commonSituations":"Assuming add_filter takes a field name or a raw expression string instead of a Filter object; migrating code from a hand-built query string; third-party wrappers that inject into _filters.","solutions":["Wrap the field in a NumericFilter or GeoFilter: from redis.commands.search.query import NumericFilter, GeoFilter; query.add_filter(NumericFilter('price', 0, 100)).","Stop mutating query._filters directly; only use add_filter().","If you need a text/expression filter, put it in the query string itself, not in add_filter()."],"exampleFix":"// before\nquery.add_filter('price')\n// after\nfrom redis.commands.search.query import NumericFilter\nquery.add_filter(NumericFilter('price', 0, 100))","handlingStrategy":"type-guard","validationCode":"from redis.commands.search.query import Filter\n\ndef add_safe_filter(query, flt):\n    if not isinstance(flt, Filter):\n        raise TypeError(\"filter must be a Filter instance\")\n    query.add_filter(flt)","typeGuard":"from redis.commands.search.query import Filter\n\ndef is_filter(val) -> bool:\n    return isinstance(val, Filter)","tryCatchPattern":"try:\n    query.add_filter(candidate)\n    query.get_args()\nexcept AttributeError:\n    # candidate was not a Filter; build one explicitly\n    pass","preventionTips":["Only pass NumericFilter or GeoFilter to add_filter().","Never assign to query._filters directly.","Put field-name/expression filters in the query string, not add_filter()."],"tags":["search","search-and-query","query","filter","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}