ruby-grape/grape · error · ArgumentError

is cannot be combined with min or max

Error message

is cannot be combined with min or max

What it means

`is:` (exact length) and `min:`/`max:` (bounds) are mutually exclusive ways to constrain length — combining an exact value with a range is either redundant or contradictory. The LengthValidator raises ArgumentError at definition time when both appear in one `length:` option hash.

Source

Thrown at lib/grape/validations/validators/length_validator.rb:17

# frozen_string_literal: true

module Grape
  module Validations
    module Validators
      class LengthValidator < Base
        def initialize(attrs, options, required, scope, opts)
          super

          @min, @max, @is = options.values_at(:min, :max, :is)
          validate_boundary!(:min, @min)
          validate_boundary!(:max, @max)
          raise ArgumentError, "min #{@min} cannot be greater than max #{@max}" if @min && @max && @min > @max

          return if @is.nil?
          raise ArgumentError, 'is must be an integer greater than zero' unless @is.is_a?(Integer) && @is.positive?
          raise ArgumentError, 'is cannot be combined with min or max' unless @min.nil? && @max.nil?
        end

        def validate_param!(attr_name, params)
          return unless hash_like?(params)

          param = params[attr_name]

          return unless param.respond_to?(:length)

          return unless (!@min.nil? && param.length < @min) || (!@max.nil? && param.length > @max) || (!@is.nil? && param.length != @is)

          validation_error!(attr_name, message do
            if @min && @max
              translate(:length, min: @min, max: @max)
            elsif @min
              translate(:length_min, min: @min)
            elsif @max
              translate(:length_max, max: @max)

View on GitHub (pinned to 22d7975629)

Solutions

  1. Keep `is:` alone for exact lengths
  2. Express exactness as `min: 5, max: 5` if you must merge with bound-style configs
  3. Delete whichever constraint was not intended

Example fix

# before
requires :zip, type: String, length: { is: 5, min: 1 }

# after
requires :zip, type: String, length: { is: 5 }
Defensive patterns

Strategy: validation

Validate before calling

def is_isolated?(length_opts)
  length_opts[:is].nil? || (length_opts[:min].nil? && length_opts[:max].nil?)
end

raise 'length is: cannot be combined with min/max' unless is_isolated?(merged_length_opts)

Try / catch

begin
  requires :zip, type: String, length: length_opts
rescue ArgumentError => e
  raise "length options conflict after merging defaults: #{e.message}"
end

Prevention

When it happens

Trigger: `length: { is: 5, min: 3 }`; `length: { is: 5, max: 8 }`; merged option hashes that combine an exact rule with bounds.

Common situations: Layering shared defaults such as `{ min: 1, max: 100 }` onto declarations that already carry `is:`; incremental edits that add a bound to an existing exact rule.

Related errors


AI-assisted analysis of ruby-grape/grape@22d7975629 (2026-08-21). Data as JSON: /api/errors/9771a44549862d5c. Report an issue: GitHub.