{"id":"128b6c4212cc708d","repo":"redis/redis-py","slug":"bad-query-type-type-query","errorCode":null,"errorMessage":"Bad query type {type(query)}","messagePattern":"Bad query type (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/commands/search/commands.py","lineNumber":1309,"sourceCode":"        args = []\n        if len(query_params) > 0:\n            args.append(\"PARAMS\")\n            args.append(len(query_params) * 2)\n            for key, value in query_params.items():\n                args.append(key)\n                args.append(value)\n        return args\n\n    def _mk_query_args(\n        self, query, query_params: Optional[Dict[str, Union[str, int, float, bytes]]]\n    ):\n        args = [self.index_name]\n\n        if isinstance(query, str):\n            # convert the query from a text to a query object\n            query = Query(query)\n        if not isinstance(query, Query):\n            raise ValueError(f\"Bad query type {type(query)}\")\n\n        args += query.get_args()\n        args += self.get_params_args(query_params)\n\n        return args, query\n\n    def search(\n        self,\n        query: Union[str, Query],\n        query_params: Union[Dict[str, Union[str, int, float, bytes]], None] = None,\n    ):\n        \"\"\"\n        Search the index for a given query, and return a result of documents\n\n        ### Parameters\n\n        - **query**: the search query. Either a text for simple queries with\n                     default parameters, or a Query object for complex queries.","sourceCodeStart":1291,"sourceCodeEnd":1327,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/search/commands.py#L1291-L1327","documentation":"Raised by _mk_query_args() (used by search(), explain(), etc.) when the query argument is neither a str nor a Query object. Strings are auto-wrapped in Query(); any other type is rejected. The library refuses to guess how to serialize arbitrary objects into a RediSearch query string.","triggerScenarios":"Call client.search(query) where query is an int, dict, list, None, or an arbitrary object that is not a Query instance and not a string.","commonSituations":"Passing a parsed JSON object or dict as the query; passing None by mistake; passing an AggregateRequest (wrong API — that goes to aggregate()).","solutions":["Pass a query string (e.g. '@title:hello') or a Query object.","Build a Query: from redis.commands.search import Query; Query('@title:hello').","For aggregation-style requests, use client.aggregate(AggregateRequest(...)) instead."],"exampleFix":"// before\nclient.search({'title': 'hello'})\n// after\nclient.search('@title:hello')\n// or\nclient.search(Query('@title:hello').paging(0, 10))","handlingStrategy":"type-guard","validationCode":"from redis.commands.search import Query\n\ndef safe_search(client, query, query_params=None):\n    if isinstance(query, str):\n        query = Query(query)\n    elif not isinstance(query, Query):\n        raise TypeError(f\"query must be str or Query, got {type(query)}\")\n    return client.search(query, query_params=query_params)","typeGuard":"from redis.commands.search import Query\n\ndef is_search_query(v) -> bool:\n    return isinstance(v, (str, Query))","tryCatchPattern":"try:\n    client.search(query)\nexcept ValueError as e:\n    if \"Bad query type\" in str(e):\n        client.search(Query(str(query)))\n    else:\n        raise","preventionTips":["Always pass either a query string or a Query object — never a dict.","Centralize query construction in one helper that returns a Query.","For aggregation needs, use aggregate(AggregateRequest(...))."],"tags":["redis-search","validation","query","valueerror"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}