redis/redis-rb · error · ArgumentError

enx requires one of ex, px, exat or pxat

Error message

enx requires one of ex, px, exat or pxat

What it means

Error "enx requires one of ex, px, exat or pxat" thrown in redis/redis-rb.

Source

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

      # @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
        args << "PXAT" << Integer(pxat) if pxat

View on GitHub (pinned to 2ba9010b91)

Solutions

  1. When passing enx: true, also pass one of ex:, px:, exat: or pxat: so there is a TTL to compare against.
  2. Remove enx: if you do not need the not-expired condition.

When it happens

Trigger: Thrown at lib/redis/commands/strings.rb:123 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/be6b1804ae60c99f. Report an issue: GitHub.