{"id":"e97031d3dc69ce10","repo":"redis/redis-py","slug":"xclaim-retrycount-must-be-an-integer","errorCode":null,"errorMessage":"XCLAIM retrycount must be an integer","messagePattern":"XCLAIM retrycount must be an integer","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":7314,"sourceCode":"                \"XCLAIM message_ids must be a non empty list or \"\n                \"tuple of message IDs to claim\"\n            )\n\n        kwargs = {}\n        pieces: list[EncodableT] = [name, groupname, consumername, str(min_idle_time)]\n        pieces.extend(list(message_ids))\n\n        if idle is not None:\n            if not isinstance(idle, int):\n                raise DataError(\"XCLAIM idle must be an integer\")\n            pieces.extend((b\"IDLE\", str(idle)))\n        if time is not None:\n            if not isinstance(time, int):\n                raise DataError(\"XCLAIM time must be an integer\")\n            pieces.extend((b\"TIME\", str(time)))\n        if retrycount is not None:\n            if not isinstance(retrycount, int):\n                raise DataError(\"XCLAIM retrycount must be an integer\")\n            pieces.extend((b\"RETRYCOUNT\", str(retrycount)))\n\n        if force:\n            if not isinstance(force, bool):\n                raise DataError(\"XCLAIM force must be a boolean\")\n            pieces.append(b\"FORCE\")\n        if justid:\n            if not isinstance(justid, bool):\n                raise DataError(\"XCLAIM justid must be a boolean\")\n            pieces.append(b\"JUSTID\")\n            kwargs[\"parse_justid\"] = True\n        return self.execute_command(\"XCLAIM\", *pieces, **kwargs)\n\n    @overload\n    def xdel(self: SyncClientProtocol, name: KeyT, *ids: StreamIdT) -> int: ...\n\n    @overload\n    def xdel(","sourceCodeStart":7296,"sourceCodeEnd":7332,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L7296-L7332","documentation":"Raised by xclaim() when the optional `retrycount` argument is provided but is not an int. Strict isinstance(int) at core.py:7313.","triggerScenarios":"xclaim(..., retrycount='3') (str), =3.0 (float). retrycount=None or omitted is valid.","commonSituations":"Passing a delivery-count from a dict/JSON as a string; a float average.","solutions":["Pass an int, or None to omit.","Coerce: retrycount = int(raw) if raw is not None else None."],"exampleFix":"# before\nr.xclaim('s','g','c', 0, ['1-0'], retrycount=msg['attempts'])  # str\n# after\nr.xclaim('s','g','c', 0, ['1-0'], retrycount=int(msg['attempts']))","handlingStrategy":"type-guard","validationCode":"rc = int(retrycount) if retrycount is not None else None\nr.xclaim(name, group, consumer, ms, ids, retrycount=rc)","typeGuard":"def opt_int(v): return v if v is None else int(v)","tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    r.xclaim(name, group, consumer, ms, ids, retrycount=rc)\nexcept DataError:\n    r.xclaim(name, group, consumer, ms, ids, retrycount=int(rc))","preventionTips":["JSON-derived numbers may arrive as str - coerce before XCLAIM."],"tags":["redis","streams","xclaim","type-guard","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}