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
- Always pair `enx=True` with exactly one of `ex`/`px`/`exat`/`pxat`.
- If you have no TTL to set, drop `enx` entirely.
- 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
- Treat enx as a modifier on a resolved TTL, not a standalone flag.
- Gate enx on having a non-None TTL upstream.
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
- ``byfloat`` and ``byint`` are mutually exclusive.
- ``ex``, ``px``, ``exat``, ``pxat``, and ``keepttl`` are…
- ``ex``, ``px``, ``exat``, ``pxat``, and ``persist`` are…
- bit must be 0 or 1
- Both start and end must be specified
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)