redis/redis-py · error · ValueError
Must provide AggregateRequest object or Query object.
Error message
Must provide AggregateRequest object or Query object.
What it means
Raised by profile() (redis/commands/search/commands.py:1514) as a ValueError when the query argument is neither an AggregateRequest nor a Query. FT.PROFILE can profile either a SEARCH or an AGGREGATE, so the client requires one of those two typed objects to know which sub-command to issue.
Solutions
- Wrap strings: index.profile(Query('*')).
- For aggregation profiling pass the AggregateRequest itself: index.profile(AggregateRequest('*')).
- Do not pass a Cursor or result object - pass the request.
Example fix
# before
index.profile('*', limited=True)
# after
from redis.commands.search.query import Query
index.profile(Query('*'), limited=True) Defensive patterns
Strategy: type-guard
Validate before calling
from redis.commands.search.query import Query
from redis.commands.search.aggregation import AggregateRequest
def safe_profile(index, query, limited=False):
if not isinstance(query, (Query, AggregateRequest)):
raise TypeError('profile() requires a Query or AggregateRequest')
return index.profile(query, limited=limited) Type guard
from redis.commands.search.query import Query
from redis.commands.search.aggregation import AggregateRequest
def is_profile_query(q) -> bool:
return isinstance(q, (Query, AggregateRequest)) Try / catch
try:
index.profile(query, limited=True)
except ValueError as e:
if 'AggregateRequest object or Query' in str(e):
index.profile(Query(str(query)), limited=True)
else:
raise Prevention
- Wrap query strings in Query(...) before profiling.
- Pass the AggregateRequest itself (not a Cursor or result) for aggregation profiling.
- Keep search and aggregation profiling inputs distinct.
When it happens
Trigger: Calling index.profile('*' ), index.profile(None), index.profile({...}), or passing a Cursor (Cursor is valid for aggregate() but not for profile()).
Common situations: Passing a raw query string instead of wrapping it in Query(...), or passing an AggregateResult/Cursor where the request object is expected.
Related errors
- Bad query type
- Bad query
- Cannot use FIELDNAME alias with no field
- Non-Sortable non-Indexable fields are ignored
- At least one tag must be specified
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/afb746a510072034.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/search/commands.py:1514
**query_params**: Define one or more value parameters.
Each parameter has a name and a value.
"""
st = time.monotonic()
cmd = [PROFILE_CMD, self.index_name, ""]
if limited:
cmd.append("LIMITED")
cmd.append("QUERY")
if isinstance(query, AggregateRequest):
cmd[2] = "AGGREGATE"
cmd += query.build_args()
elif isinstance(query, Query):
cmd[2] = "SEARCH"
cmd += query.get_args()
cmd += self.get_params_args(query_params)
else:
raise ValueError("Must provide AggregateRequest object or Query object.")
res = self.execute_command(*cmd)
return self._parse_results(
PROFILE_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0
)
def spellcheck(self, query, distance=None, include=None, exclude=None):
"""
Issue a spellcheck query
Args:
query: search query.
distance: the maximal Levenshtein distance for spelling
suggestions (default: 1, max: 4).
include: specifies an inclusion custom dictionary.
exclude: specifies an exclusion custom dictionary.View on GitHub (pinned to 6a6b581b48)