{"record":{"id":"be6b1804ae60c99f","repo":"redis/redis-rb","slug":"enx-requires-one-of-ex-px-exat-or-pxat","errorCode":null,"errorMessage":"enx requires one of ex, px, exat or pxat","messagePattern":"enx requires one of ex, px, exat or pxat","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/redis/commands/strings.rb","lineNumber":123,"sourceCode":"      # @param [Integer] ex expiration in seconds\n      # @param [Integer] px expiration in milliseconds\n      # @param [Integer] exat expiration as a Unix timestamp in seconds\n      # @param [Integer] pxat expiration as a Unix timestamp in milliseconds\n      # @param [Boolean] persist remove the key's expiration\n      # @param [Boolean] enx only set the expiration when the key has no TTL\n      #   (the increment is applied regardless); requires one of\n      #   `ex`/`px`/`exat`/`pxat`\n      # @return [Array(Integer, Integer), Array(Float, Float)]\n      #   `[new_value, applied_increment]` — Integers in integer mode, Floats\n      #   in float mode (under RESP2 and RESP3 alike); `applied_increment`\n      #   is 0 when the operation was skipped as out of bounds\n      def increx(key, by: nil, lbound: nil, ubound: nil, saturate: nil,\n                 ex: nil, px: nil, exat: nil, pxat: nil, persist: nil, enx: nil)\n        if [ex, px, exat, pxat, persist].count { |option| option } > 1\n          raise ArgumentError, \"ex, px, exat, pxat and persist are mutually exclusive\"\n        end\n        raise ArgumentError, \"enx is incompatible with persist\" if enx && persist\n        raise ArgumentError, \"enx requires one of ex, px, exat or pxat\" if enx && !(ex || px || exat || pxat)\n\n        # The Ruby type of `by` selects the wire mode; anything else would\n        # have to silently pick a mode, so it is rejected instead.\n        float_mode = case by\n        when nil, Integer then false\n        when Float then true\n        else raise TypeError, \"by must be an Integer (BYINT) or a Float (BYFLOAT), got #{by.class}\"\n        end\n\n        args = [:increx, key]\n        args << (float_mode ? \"BYFLOAT\" : \"BYINT\") << by if by\n        args << \"LBOUND\" << increx_bound(:lbound, lbound, float_mode) if lbound\n        args << \"UBOUND\" << increx_bound(:ubound, ubound, float_mode) if ubound\n        args << \"SATURATE\" if saturate\n        args << \"EX\" << Integer(ex) if ex\n        args << \"PX\" << Integer(px) if px\n        args << \"EXAT\" << Integer(exat) if exat\n        args << \"PXAT\" << Integer(pxat) if pxat","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/redis/redis-rb/blob/2ba9010b91dab9e0fde1fbae3a9aae003f8bc307/lib/redis/commands/strings.rb#L105-L141","documentation":"Error \"enx requires one of ex, px, exat or pxat\" thrown in redis/redis-rb.","triggerScenarios":"Thrown at lib/redis/commands/strings.rb:123 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["When passing enx: true, also pass one of ex:, px:, exat: or pxat: so there is a TTL to compare against.","Remove enx: if you do not need the not-expired condition."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"2ba9010b91dab9e0fde1fbae3a9aae003f8bc307","analyzedAt":"2026-08-23T03:54:57.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}