redis/redis-py · error · DataError

``byfloat`` and ``byint`` are mutually exclusive.

Error message

``byfloat`` and ``byint`` are mutually exclusive.

What it means

Raised as a `DataError` by `increx()` (redis/commands/core.py:3478) when both `byfloat` and `byint` are supplied. INCREX increments by either a float or an int (defaulting to +1 if neither is given); specifying both is contradictory.

Solutions

  1. Pass either `byfloat` (for fractional increments) or `byint` (for integer increments), not both.
  2. Omit both for a default +1 increment.
  3. Resolve the increment type upstream and forward a single kwarg.

Example fix

// before
r.increx('c', byfloat=1.5, byint=2)
// after
r.increx('c', byint=2)  # integer increment by 2
Defensive patterns

Strategy: validation

Validate before calling

if byfloat is not None and byint is not None:
    raise ValueError('increx: pass byfloat OR byint, not both')
r.increx('c', byfloat=byfloat, byint=byint)

Prevention

When it happens

Trigger: `r.increx('counter', byfloat=1.5, byint=2)` or any call passing both keyword args.

Common situations: Generic increment helpers that forward both kwargs from a config object; experimental API discovery (INCREX is new); logic that decides float-vs-int but forwards both.

Related errors


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

Appendix: source

Thrown at redis/commands/core.py:3484

        ``lbound`` and ``ubound`` constrain the valid range of the result.

        If ``saturate`` is True, out-of-bounds results are saturated to the
        specified bound, or to the type limit when no bound is specified.
        Otherwise, out-of-bounds results are rejected, leaving the value and
        TTL unchanged and returning the current value and zero as the actual
        increment.

        ``enx`` applies the expiration only when the key does not already
        have an expiration, and requires ``ex``, ``px``, ``exat``, or ``pxat``.
        """
        if not at_most_one_value_set(
            (
                byfloat is not None,
                byint is not None,
            )
        ):
            raise DataError("``byfloat`` and ``byint`` are mutually exclusive.")

        if not at_most_one_value_set(
            (
                ex is not None,
                px is not None,
                exat is not None,
                pxat is not None,
                persist,
            )
        ):
            raise DataError(
                "``ex``, ``px``, ``exat``, ``pxat``, "
                "and ``persist`` are mutually exclusive."
            )

        if enx and ex is None and px is None and exat is None and pxat is None:
            raise DataError(
                "``enx`` requires one of ``ex``, ``px``, ``exat``, or ``pxat``."

View on GitHub (pinned to 6a6b581b48)