redis/redis-py · error · DataError

Invalid input of type: 'bool'. Convert to a bytes, string…

Error message

Invalid input of type: 'bool'. Convert to a bytes, string, int or float first.

What it means

Raised by Encoder.encode() (redis/_parsers/encoders.py:20) when a Python bool is passed as a value to encode. Because bool is a subclass of int, the encoder special-cases it before the int branch to avoid silently serializing True->1 / False->0. It raises DataError asking the caller to convert explicitly to bytes/str/int/float.

Solutions

  1. Convert the bool explicitly before sending: int(flag) for 1/0, or str(flag).encode()/encode the string.
  2. Adopt a serialization convention for booleans (e.g. 'true'/'false', 1/0) at the application boundary.
  3. Use a wrapper/codec so values are normalized before reaching the client.

Example fix

# before
r.set("enabled", feature.enabled)  # DataError: Invalid input of type: 'bool'

# after
r.set("enabled", int(feature.enabled))  # or "true"/"false"
Defensive patterns

Strategy: type-guard

Validate before calling

# Normalize booleans to a RESP-safe value before sending
def coerce(v):
    return int(v) if isinstance(v, bool) else v
r.set("k", coerce(feature.enabled))

Type guard

def is_bool(v) -> bool:
    return isinstance(v, bool)

Try / catch

from redis.exceptions import DataError
try:
    r.set("k", value)
except DataError as e:
    if "type: 'bool'" in str(e):
        r.set("k", int(value))

Prevention

When it happens

Trigger: Passing a boolean as a Redis value or argument: r.set('flag', True), HSET with a bool field value, passing a bool into any command whose args flow through the encoder (most do).

Common situations: Storing feature/config flags; serializing Python objects that contain bools; forwarding bool kwargs/returns into commands; ORM/dataclass dumps that leave bools unconverted.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/b160a9b03fba202a. Report an issue: GitHub.

Appendix: source

Thrown at redis/_parsers/encoders.py:20


class Encoder:
    "Encode strings to bytes-like and decode bytes-like to strings"

    __slots__ = "encoding", "encoding_errors", "decode_responses"

    def __init__(self, encoding, encoding_errors, decode_responses):
        self.encoding = encoding
        self.encoding_errors = encoding_errors
        self.decode_responses = decode_responses

    def encode(self, value):
        "Return a bytestring or bytes-like representation of the value"
        if isinstance(value, (bytes, bytearray, memoryview)):
            return value
        elif isinstance(value, bool):
            # special case bool since it is a subclass of int
            raise DataError(
                "Invalid input of type: 'bool'. Convert to a "
                "bytes, string, int or float first."
            )
        elif isinstance(value, (int, float)):
            value = repr(value).encode()
        elif not isinstance(value, str):
            # a value we don't know how to deal with. throw an error
            typename = type(value).__name__
            raise DataError(
                f"Invalid input of type: '{typename}'. "
                f"Convert to a bytes, string, int or float first."
            )
        if isinstance(value, str):
            value = value.encode(self.encoding, self.encoding_errors)
        return value

    def decode(self, value, force=False):
        "Return a unicode string from the bytes-like representation"

View on GitHub (pinned to 6a6b581b48)