redis/redis-py · error · DataError
XCLAIM force must be a boolean
Error message
XCLAIM force must be a boolean
What it means
Raised by xclaim() when `force` is truthy but not a bool. IMPORTANT: the guard lives under `if force:` (core.py:7317), so falsy non-bools (0, '', None) are silently treated as False and never trip this - only truthy non-bools like 1, 'yes', 'true' raise.
Source
Thrown at redis/commands/core.py:7319
pieces: list[EncodableT] = [name, groupname, consumername, str(min_idle_time)]
pieces.extend(list(message_ids))
if idle is not None:
if not isinstance(idle, int):
raise DataError("XCLAIM idle must be an integer")
pieces.extend((b"IDLE", str(idle)))
if time is not None:
if not isinstance(time, int):
raise DataError("XCLAIM time must be an integer")
pieces.extend((b"TIME", str(time)))
if retrycount is not None:
if not isinstance(retrycount, int):
raise DataError("XCLAIM retrycount must be an integer")
pieces.extend((b"RETRYCOUNT", str(retrycount)))
if force:
if not isinstance(force, bool):
raise DataError("XCLAIM force must be a boolean")
pieces.append(b"FORCE")
if justid:
if not isinstance(justid, bool):
raise DataError("XCLAIM justid must be a boolean")
pieces.append(b"JUSTID")
kwargs["parse_justid"] = True
return self.execute_command("XCLAIM", *pieces, **kwargs)
@overload
def xdel(self: SyncClientProtocol, name: KeyT, *ids: StreamIdT) -> int: ...
@overload
def xdel(
self: AsyncClientProtocol, name: KeyT, *ids: StreamIdT
) -> Awaitable[int]: ...
def xdel(self, name: KeyT, *ids: StreamIdT) -> int | Awaitable[int]:
"""View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass an actual Python bool: force=bool(flag).
- For string flags, normalize: flag_str.lower() in {'1','true','yes'}.
- Note the asymmetry: 0 slips through but 1 does not - always bool()-coerce to be safe.
Example fix
# before
r.xclaim('s','g','c', 0, ['1-0'], force=cfg['force']) # 'true' -> fails
# after
r.xclaim('s','g','c', 0, ['1-0'], force=str(cfg['force']).lower() in {'1','true','yes'}) Defensive patterns
Strategy: type-guard
Validate before calling
force = bool(force) r.xclaim(name, group, consumer, ms, ids, force=force)
Type guard
def as_bool(v) -> bool:
if isinstance(v, bool): return v
if isinstance(v, str): return v.strip().lower() in {'1','true','yes','on'}
return bool(v) Try / catch
from redis.exceptions import DataError
try:
r.xclaim(name, group, consumer, ms, ids, force=force)
except DataError:
r.xclaim(name, group, consumer, ms, ids, force=bool(force)) Prevention
- Always bool()-coerce flag values from config/UI.
- Remember the guard only fires for truthy non-bools.
When it happens
Trigger: xclaim(..., force=1), =force='yes'), =force='true'). force=0/None/'' does NOT raise (treated as False). force=True is correct.
Common situations: Passing force from a config flag that is a string 'true'; an int 0/1 from a checkbox; a numpy bool_.
Related errors
- XCLAIM justid must be a boolean
- XCLAIM min_idle_time must be a non negative integer
- XCLAIM idle must be an integer
- XCLAIM time must be an integer
- XCLAIM retrycount must be an integer
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/8c9dbbe5481f4392.json.
Report an issue: GitHub.