redis/redis-rb · error · ArgumentError

enx is incompatible with persist

Error message

enx is incompatible with persist

What it means

Error "enx is incompatible with persist" thrown in redis/redis-rb.

Source

Thrown at lib/redis/commands/strings.rb:122

      #   bound instead of skipping the operation
      # @param [Integer] ex expiration in seconds
      # @param [Integer] px expiration in milliseconds
      # @param [Integer] exat expiration as a Unix timestamp in seconds
      # @param [Integer] pxat expiration as a Unix timestamp in milliseconds
      # @param [Boolean] persist remove the key's expiration
      # @param [Boolean] enx only set the expiration when the key has no TTL
      #   (the increment is applied regardless); requires one of
      #   `ex`/`px`/`exat`/`pxat`
      # @return [Array(Integer, Integer), Array(Float, Float)]
      #   `[new_value, applied_increment]` — Integers in integer mode, Floats
      #   in float mode (under RESP2 and RESP3 alike); `applied_increment`
      #   is 0 when the operation was skipped as out of bounds
      def increx(key, by: nil, lbound: nil, ubound: nil, saturate: nil,
                 ex: nil, px: nil, exat: nil, pxat: nil, persist: nil, enx: nil)
        if [ex, px, exat, pxat, persist].count { |option| option } > 1
          raise ArgumentError, "ex, px, exat, pxat and persist are mutually exclusive"
        end
        raise ArgumentError, "enx is incompatible with persist" if enx && persist
        raise ArgumentError, "enx requires one of ex, px, exat or pxat" if enx && !(ex || px || exat || pxat)

        # The Ruby type of `by` selects the wire mode; anything else would
        # have to silently pick a mode, so it is rejected instead.
        float_mode = case by
        when nil, Integer then false
        when Float then true
        else raise TypeError, "by must be an Integer (BYINT) or a Float (BYFLOAT), got #{by.class}"
        end

        args = [:increx, key]
        args << (float_mode ? "BYFLOAT" : "BYINT") << by if by
        args << "LBOUND" << increx_bound(:lbound, lbound, float_mode) if lbound
        args << "UBOUND" << increx_bound(:ubound, ubound, float_mode) if ubound
        args << "SATURATE" if saturate
        args << "EX" << Integer(ex) if ex
        args << "PX" << Integer(px) if px
        args << "EXAT" << Integer(exat) if exat

View on GitHub (pinned to 2ba9010b91)

Solutions

  1. Do not combine enx: true with persist: true; persist removes the TTL that enx depends on.
  2. Choose either the enx conditional-set behavior or persist, not both.

When it happens

Trigger: Thrown at lib/redis/commands/strings.rb:122 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of redis/redis-rb@2ba9010b91 (2026-08-23). Data as JSON: /api/errors/20a8f7d16a359f02. Report an issue: GitHub.