{"record":{"id":"a52eef52d1e94e6d","repo":"redis/redis-py","slug":"block-min-count-requires-block-milliseconds-to-be","errorCode":null,"errorMessage":"block_min_count requires block_milliseconds to be set; the BLOCK group is all-or-nothing.","messagePattern":"block_min_count requires block_milliseconds to be set; the BLOCK group is all-or-nothing\\.","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/timeseries/commands.py","lineNumber":1999,"sourceCode":"        if count is not None:\n            params.extend([\"COUNT\", count])\n\n    @staticmethod\n    def _append_block(\n        params: list[EncodableT],\n        block_milliseconds: int | None,\n        block_min_count: int | None,\n    ):\n        \"\"\"Append the BLOCK group to params.\n\n        The BLOCK group is all-or-nothing: when blocking is requested\n        (`block_milliseconds` is set), both `milliseconds` and `min_count` are\n        always emitted, with `min_count` defaulting to 1. There is no standalone\n        MIN_COUNT keyword in this command.\n        \"\"\"\n        if block_milliseconds is None:\n            if block_min_count is not None:\n                raise DataError(\n                    \"block_min_count requires block_milliseconds to be set; the \"\n                    \"BLOCK group is all-or-nothing.\"\n                )\n            return\n        min_count = 1 if block_min_count is None else block_min_count\n        params.extend([\"BLOCK\", block_milliseconds, min_count])\n\n    @staticmethod\n    def _append_max_count(params: list[EncodableT], max_count: int | None):\n        \"\"\"Append MAX_COUNT property to params.\"\"\"\n        if max_count is not None:\n            params.extend([\"MAX_COUNT\", max_count])\n\n    @staticmethod\n    def _append_timestamp(params: list[EncodableT], timestamp: int | None):\n        \"\"\"Append TIMESTAMP property to params.\"\"\"\n        if timestamp is not None:\n            params.extend([\"TIMESTAMP\", timestamp])","sourceCodeStart":1981,"sourceCodeEnd":2017,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/timeseries/commands.py#L1981-L2017","documentation":"Raised by _append_block (used by TS.RANGE/XRANGE-style blocking reads) when block_min_count is set but block_milliseconds is None. The BLOCK clause is all-or-nothing on the wire: blocking requires the milliseconds value, and min_count alone is not a valid standalone keyword.","triggerScenarios":"Calling a range read with block_min_count=5 but block_milliseconds=None (omitted). Passing only the min_count half of a blocking pair.","commonSituations":"Config objects that map block_min_count without block_milliseconds. Partial migration where one parameter was renamed or dropped.","solutions":["Always set block_milliseconds when you set block_min_count.","If you do not want blocking, omit both block_milliseconds and block_min_count.","Validate the pair together in your wrapper before calling the API."],"exampleFix":"// before\nclient.ts().range(key, f, t,\n    block_milliseconds=None, block_min_count=5)\n// after\nclient.ts().range(key, f, t,\n    block_milliseconds=1000, block_min_count=5)\n# or non-blocking: omit both","handlingStrategy":"validation","validationCode":"if block_min_count is not None and block_milliseconds is None:\n    raise ValueError('block_milliseconds required when block_min_count is set')\nclient.ts().range(key, f, t, block_milliseconds=block_milliseconds, block_min_count=block_min_count)","typeGuard":null,"tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    client.ts().range(key, f, t, block_milliseconds=block_milliseconds, block_min_count=block_min_count)\nexcept DataError:\n    client.ts().range(key, f, t)  # fall back to non-blocking","preventionTips":["Treat block_milliseconds and block_min_count as a single optional pair.","Validate the pair together in config loaders."],"tags":["redistimeseries","block","range","argument-validation"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}