{"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/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/timeseries/commands.py#L1981-L2017","documentation":"Raised by _append_block (used by TS.READ) when block_min_count is set but block_milliseconds is None. The BLOCK group on the wire is all-or-nothing: blocking is opted into via block_milliseconds, and min_count defaults to 1 only when blocking is enabled. Supplying a threshold without enabling blocking is a usage error.","triggerScenarios":"client.ts().read('key', '$', block_min_count=5) with block_milliseconds left as None.","commonSituations":"Configuring the unblock threshold but forgetting the block duration; passing a partial BLOCK config from a dict that omitted milliseconds; assuming min_count alone enables blocking.","solutions":["Set block_milliseconds alongside block_min_count: client.ts().read('key', '$', block_milliseconds=5000, block_min_count=5).","If you do not want blocking, remove block_min_count entirely.","Also raise the client socket_timeout above block_milliseconds to avoid a premature TimeoutError."],"exampleFix":"// before\nclient.ts().read('key', '$', block_min_count=5)\n// after\nclient.ts().read('key', '$', block_milliseconds=5000, block_min_count=5)","handlingStrategy":"validation","validationCode":"def normalize_block(block_ms, block_min_count):\n    if block_min_count is not None and block_ms is None:\n        raise ValueError(\"block_min_count requires block_milliseconds\")\n    return block_ms, block_min_count\n\n# usage: client.ts().read('k', '$', *normalize_block(ms, mc))","typeGuard":"def block_args_valid(block_ms, block_min_count) -> bool:\n    return block_ms is not None or block_min_count is None","tryCatchPattern":"try:\n    client.ts().read('k', '$', block_min_count=mc)\nexcept Exception as e:\n    if 'block_min_count requires' in str(e):\n        client.ts().read('k', '$', block_milliseconds=5000, block_min_count=mc)\n    else:\n        raise","preventionTips":["Always set block_milliseconds when setting block_min_count.","Raise socket_timeout above the block window when blocking.","Keep the BLOCK group as one unit in config."],"tags":["redistimeseries","timeseries","read","blocking","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}