{"id":"e343dfd927e68ffb","repo":"redis/redis-py","slug":"xautoclaim-min-idle-time-must-be-a-nonnegative-int","errorCode":null,"errorMessage":"XAUTOCLAIM min_idle_time must be a nonnegative integer","messagePattern":"XAUTOCLAIM min_idle_time must be a nonnegative integer","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":7194,"sourceCode":"        criteria. Conceptually, equivalent to calling XPENDING and then XCLAIM,\n        but provides a more straightforward way to deal with message delivery\n        failures via SCAN-like semantics.\n        name: name of the stream.\n        groupname: name of the consumer group.\n        consumername: name of a consumer that claims the message.\n        min_idle_time: filter messages that were idle less than this amount of\n        milliseconds.\n        start_id: filter messages with equal or greater ID.\n        count: optional integer, upper limit of the number of entries that the\n        command attempts to claim. Set to 100 by default.\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/xautoclaim\n        \"\"\"\n        try:\n            if int(min_idle_time) < 0:\n                raise DataError(\n                    \"XAUTOCLAIM min_idle_time must be a nonnegative integer\"\n                )\n        except TypeError:\n            pass\n\n        kwargs = {}\n        pieces = [name, groupname, consumername, min_idle_time, start_id]\n\n        try:\n            if int(count) < 0:\n                raise DataError(\"XPENDING count must be a integer >= 0\")\n            pieces.extend([b\"COUNT\", count])\n        except TypeError:\n            pass\n        if justid:\n            pieces.append(b\"JUSTID\")\n            kwargs[\"parse_justid\"] = True\n","sourceCodeStart":7176,"sourceCodeEnd":7212,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L7176-L7212","documentation":"Raised by xautoclaim() when min_idle_time, after int() coercion, is negative. CAUTION: the guard is wrapped in try/except TypeError, so values int() cannot parse (None, lists, etc.) are SWALLOWED and forwarded to Redis - only a successfully-parsed negative trips this. This is stricter than xclaim, which uses isinstance.","triggerScenarios":"xautoclaim(name, group, consumer, min_idle_time=-1) or ='-1' (int('-1') == -1). Passing min_idle_time=None or ='abc' does NOT raise here - it slips through to the server.","commonSituations":"Computing idle from a clock-skewed delta that went negative; using -1 as a 'no filter' sentinel; passing a float like 5.5 (int() truncates to 5, ok) - but a negative float truncates to a negative int and trips.","solutions":["Pass 0 (not negative) when you want no idle filtering.","Clamp upstream: min_idle_time = max(0, int(value)).","Do not rely on this guard to catch non-numeric junk - validate the type yourself."],"exampleFix":"# before\nr.xautoclaim('s','g','c', min_idle_time=delta_ms)  # delta_ms < 0\n# after\nr.xautoclaim('s','g','c', min_idle_time=max(0, int(delta_ms)))","handlingStrategy":"validation","validationCode":"idle = max(0, int(min_idle_time)) if min_idle_time is not None else 0\nr.xautoclaim(name, group, consumer, idle)","typeGuard":null,"tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    r.xautoclaim(name, group, consumer, ms)\nexcept DataError:\n    r.xautoclaim(name, group, consumer, max(0, int(ms)))","preventionTips":["Use 0 for 'claim anything idle', never a negative sentinel.","Pre-validate the type; the library's try/except silently passes non-int-coercible values."],"tags":["redis","streams","xautoclaim","validation","range-error","weak-guard"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}