{"id":"3f5f2e7f5aa9db33","repo":"redis/redis-py","slug":"xclaim-min-idle-time-must-be-a-non-negative-intege","errorCode":null,"errorMessage":"XCLAIM min_idle_time must be a non negative integer","messagePattern":"XCLAIM min_idle_time must be a non negative integer","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":7293,"sourceCode":"        time: optional integer. This is the same as idle but instead of a\n        relative amount of milliseconds, it sets the idle time to a specific\n        Unix time (in milliseconds).\n\n        retrycount: optional integer. set the retry counter to the specified\n        value. This counter is incremented every time a message is delivered\n        again.\n\n        force: optional boolean, false by default. Creates the pending message\n        entry in the PEL even if certain specified IDs are not already in the\n        PEL assigned to a different client.\n\n        justid: optional boolean, false by default. Return just an array of IDs\n        of messages successfully claimed, without returning the actual message\n\n        For more information, see https://redis.io/commands/xclaim\n        \"\"\"\n        if not isinstance(min_idle_time, int) or min_idle_time < 0:\n            raise DataError(\"XCLAIM min_idle_time must be a non negative integer\")\n        if not isinstance(message_ids, (list, tuple)) or not message_ids:\n            raise DataError(\n                \"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)))","sourceCodeStart":7275,"sourceCodeEnd":7311,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L7275-L7311","documentation":"Raised by xclaim() when min_idle_time is not an int or is negative. Unlike xautoclaim, this uses a STRICT isinstance(int) test (core.py:7292), so floats and strings are rejected here; bool passes because bool subclasses int.","triggerScenarios":"xclaim(..., min_idle_time=5.0) (float), ='5' (str), =-1. bool like True is accepted as 1.","commonSituations":"Carrying a float milliseconds value through; reading a string from config; passing a numpy int (not a Python int).","solutions":["Pass a Python int >= 0.","Coerce: min_idle_time = int(max(0, value)) - but only if you know the value is numeric.","Watch for numpy/pandas scalar types - cast with int()."],"exampleFix":"# before\nr.xclaim('s','g','c', 5.5, ['1-0'])  # float -> fails\n# after\nr.xclaim('s','g','c', int(5.5), ['1-0'])","handlingStrategy":"type-guard","validationCode":"assert isinstance(min_idle_time, int) and min_idle_time >= 0, 'min_idle_time must be int >= 0'\nr.xclaim(name, group, consumer, min_idle_time, ids)","typeGuard":"def is_nonneg_int(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool) and v >= 0","tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    r.xclaim(name, group, consumer, ms, ids)\nexcept DataError:\n    r.xclaim(name, group, consumer, int(max(0, ms)), ids)","preventionTips":["Keep idle values as plain Python ints, not floats or numpy scalars.","Strict isinstance - '5' and 5.0 are both rejected."],"tags":["redis","streams","xclaim","type-guard","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}