redis/redis-py · error · DataError

``enx`` requires one of ``ex``, ``px``, ``exat``, or…

Error message

``enx`` requires one of ``ex``, ``px``, ``exat``, or ``pxat``.

What it means

Raised as a `DataError` by `increx()` (redis/commands/core.py:3500) when `enx=True` is set but none of `ex`, `px`, `exat`, `pxat` is provided. The `enx` flag means 'apply expiration only when the key has no existing TTL' — it is meaningless without an expiration to apply.

Solutions

  1. Always pair `enx=True` with exactly one of `ex`/`px`/`exat`/`pxat`.
  2. If you have no TTL to set, drop `enx` entirely.
  3. Validate that your TTL variable is non-None before enabling `enx`.

Example fix

// before
r.increx('c', byint=1, enx=True)  # no expiry supplied
// after
r.increx('c', byint=1, ex=60, enx=True)  # set 60s TTL only if none exists
Defensive patterns

Strategy: validation

Validate before calling

if enx and ex is None and px is None and exat is None and pxat is None:
    raise ValueError('increx: enx requires one of ex/px/exat/pxat')
r.increx('c', byint=1, ex=ex, enx=enx)

Prevention

When it happens

Trigger: `r.increx('c', byint=1, enx=True)` with no expiry kwarg.

Common situations: Setting `enx` from a config flag without also resolving a TTL; assuming `enx` alone implies a default expiry; building conditional-TTL logic that drops the TTL value in some branch.

Related errors


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

Appendix: source

Thrown at redis/commands/core.py:3501

        ):
            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``."
            )

        pieces: list[EncodableT] = [name]

        if byfloat is not None:
            pieces.extend(("BYFLOAT", byfloat))
        elif byint is not None:
            pieces.extend(("BYINT", byint))

        if lbound is not None:
            pieces.extend(("LBOUND", lbound))
        if ubound is not None:
            pieces.extend(("UBOUND", ubound))
        if saturate:
            pieces.append("SATURATE")

        pieces.extend(extract_expire_flags(ex, px, exat, pxat))

View on GitHub (pinned to 6a6b581b48)