redis/redis-py · error · DataError
``ex``, ``px``, ``exat``, ``pxat``, and ``persist`` are…
Error message
``ex``, ``px``, ``exat``, ``pxat``, and ``persist`` are mutually exclusive.
What it means
Raised as a `DataError` by `getex()` (redis/commands/core.py:3274) via `at_most_one_value_set(...)` when more than one of `ex`, `px`, `exat`, `pxat`, or `persist` is set. GETEX sets exactly one expiration policy (or PERSIST to remove TTL); combining them is ambiguous and rejected client-side.
Solutions
- Choose exactly one expiration form (seconds via `ex`, ms via `px`, absolute seconds via `exat`, absolute ms via `pxat`, or `persist=True`).
- Build the expiry choice through a single resolved variable rather than passing multiple.
- Validate with `at_most_one_value_set` yourself if you wrap the call.
Example fix
// before
r.getex('k', ex=10, px=1000)
// after
r.getex('k', ex=10) # 10-second TTL Defensive patterns
Strategy: validation
Validate before calling
exp_args = [ex, px, exat, pxat]
set_exp = [a for a in exp_args if a is not None]
if len(set_exp) + (1 if persist else 0) > 1:
raise ValueError('getex: at most one expiry option allowed')
r.getex('k', **({} if not set_exp else {'ex': set_exp[0]})) Prevention
- Reuse the library's own at_most_one_value_set helper in wrappers.
- Represent TTL as one canonical field plus a unit enum.
When it happens
Trigger: `r.getex('k', ex=10, px=1000)`, `r.getex('k', ex=10, persist=True)`, or any call where two or more of those expiry kwargs are non-None/non-False.
Common situations: Generic 'set expiry' helper that forwards a dict of kwargs and accidentally overlaps; refactoring code that previously set TTL separately; defaults that collide with explicit args.
Related errors
- ``enx`` requires one of ``ex``, ``px``, ``exat``, or…
- ``ex``, ``px``, ``exat``, ``pxat``, and ``keepttl`` are…
- bit must be 0 or 1
- Both start and end must be specified
- ``byfloat`` and ``byint`` are mutually exclusive.
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/5676bf36fbc0698f.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/core.py:3283
specified in unix time.
``pxat`` sets an expire flag on key ``name`` for ``ex`` milliseconds,
specified in unix time.
``persist`` remove the time to live associated with ``name``.
For more information, see https://redis.io/commands/getex
"""
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."
)
exp_options: list[EncodableT] = extract_expire_flags(ex, px, exat, pxat)
if persist:
exp_options.append("PERSIST")
return self.execute_command("GETEX", name, *exp_options)
def __getitem__(self, name: KeyT):
"""
Return the value at key ``name``, raises a KeyError if the key
doesn't exist.
"""
value = self.get(name)
if value is not None:View on GitHub (pinned to 6a6b581b48)