{"id":"c24f7a0c4e9270f4","repo":"redis/redis-py","slug":"acl-log-count-must-be-an-integer","errorCode":null,"errorMessage":"ACL LOG count must be an integer","messagePattern":"ACL LOG count must be an integer","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":291,"sourceCode":"    @overload\n    def acl_log(\n        self: AsyncClientProtocol, count: int | None = None, **kwargs\n    ) -> Awaitable[ACLLogData]: ...\n\n    def acl_log(\n        self, count: int | None = None, **kwargs\n    ) -> ACLLogData | Awaitable[ACLLogData]:\n        \"\"\"\n        Get ACL logs as a list.\n        :param int count: Get logs[0:count].\n        :rtype: List.\n\n        For more information, see https://redis.io/commands/acl-log\n        \"\"\"\n        args = []\n        if count is not None:\n            if not isinstance(count, int):\n                raise DataError(\"ACL LOG count must be an integer\")\n            args.append(count)\n\n        return self.execute_command(\"ACL LOG\", *args, **kwargs)\n\n    @overload\n    def acl_log_reset(self: SyncClientProtocol, **kwargs) -> bool: ...\n\n    @overload\n    def acl_log_reset(self: AsyncClientProtocol, **kwargs) -> Awaitable[bool]: ...\n\n    def acl_log_reset(self, **kwargs) -> bool | Awaitable[bool]:\n        \"\"\"\n        Reset ACL logs.\n        :rtype: Boolean.\n\n        For more information, see https://redis.io/commands/acl-log\n        \"\"\"\n        args = [b\"RESET\"]","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/core.py#L273-L309","documentation":"Raised by acl_log() as a DataError when count is supplied but is not an int (isinstance(count, int) is False at redis/commands/core.py:290). The guard is strict type-based, not conversion-based — a float like 5.0 or a numeric string '5' is rejected even though they look numeric. Note bool is a subclass of int and would slip through.","triggerScenarios":"Calling r.acl_log(count) where count is a float (5.0), a string ('10'), a Decimal, or any non-int numeric. Passing None is fine (count omitted). Passing a bool is technically accepted due to int subclassing.","commonSituations":"count sourced from JSON/config as a string or float; division/computation producing a float that is then passed directly; API layer forwarding query params as strings.","solutions":["Pass a real int, e.g. r.acl_log(int(count)).","Coerce at the boundary: count = int(count) before calling, after confirming it is numeric.","If count may be a string from HTTP input, parse and validate with int() first."],"exampleFix":"# before\nr.acl_log(count='20')      # str -> DataError\nr.acl_log(count=10.0)      # float -> DataError\n# after\nr.acl_log(count=int('20'))\nr.acl_log(count=int(10.0))","handlingStrategy":"type-guard","validationCode":"if count is not None and not isinstance(count, int):\n    count = int(count)  # or raise for the caller\nclient.acl_log(count=count)","typeGuard":"def is_int_count(count) -> bool:\n    return count is None or (isinstance(count, int) and not isinstance(count, bool))","tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    client.acl_log(count=count)\nexcept DataError:\n    client.acl_log(count=int(count))","preventionTips":["Coerce count to int at the HTTP/config boundary.","Remember bool passes the isinstance(int) check — exclude it if unintended."],"tags":["acl","validation","type","acl-log","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}