{"record":{"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":"exception","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/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/core.py#L273-L309","documentation":"Raised by Redis.acl_log() when the `count` argument is supplied but is not an instance of int. The library explicitly type-checks count with isinstance(count, int) before appending it to the ACL LOG command arguments; a bool True/False would pass (bool is a subclass of int) but strings, floats, or None-with-typing are rejected. This guards the wire format, which requires an integer count.","triggerScenarios":"Calling client.acl_log(count='10') with a string, count=10.5 with a float, or count=[10] with a list. Passing count=None does NOT trigger this (None short-circuits the check) but a truthy non-int does.","commonSituations":"Loading count from a config file/env var as a string and passing it through without coercion; reading a query parameter in a web handler and forwarding it as-is.","solutions":["Coerce count to int before calling: client.acl_log(count=int(count_str)).","Omit count (or pass None) to fetch all log entries.","Validate the source value and surface a clearer error to the caller."],"exampleFix":"# before\nclient.acl_log(count=request.args.get('count'))  # string from HTTP\n# after\nclient.acl_log(count=int(request.args.get('count')))","handlingStrategy":"validation","validationCode":"def safe_acl_log(client, count=None):\n    if count is not None and not isinstance(count, int):\n        count = int(count)\n    return client.acl_log(count=count)","typeGuard":"def is_int_count(count) -> bool:\n    # note: bool is a subclass of int and passes isinstance; reject bool explicitly if undesired\n    return count is None or (isinstance(count, int) and not isinstance(count, bool))","tryCatchPattern":"from redis.exceptions import DataError\ntry:\n    logs = client.acl_log(count=count)\nexcept DataError as e:\n    if 'must be an integer' in str(e):\n        logs = client.acl_log(count=int(count))\n    else:\n        raise","preventionTips":["Coerce count from string sources with int() before calling.","Pass None instead of a string '0' to mean 'all entries'.","Add a thin wrapper that centralizes type coercion for ACL calls."],"tags":["acl","validation","acl-log","input-validation","type-check"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}