ruby-grape/grape · error · ArgumentError

min #{@min} cannot be greater than max #{@max}

Error message

min #{@min} cannot be greater than max #{@max}

What it means

Grape's `length` validator constrains a param's length with `min:`/`max:`/`is:`. Bounds are validated when the API class is defined: a pair where `min` is greater than `max` describes an empty range — every incoming value would fail — so Grape raises ArgumentError immediately instead of at request time.

Source

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

# 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)

View on GitHub (pinned to 22d7975629)

Solutions

  1. Fix the pair so `min <= max`
  2. When bounds come from config, validate them at boot (`raise 'bad config' unless min <= max`) so the failure is attributed to configuration, not the DSL
  3. Derive both ends from one Range constant to keep them consistent: `RANGE = 2..8` then `length: { min: RANGE.min, max: RANGE.max }`

Example fix

# before
requires :name, type: String, length: { min: 10, max: 5 }

# after
requires :name, type: String, length: { min: 5, max: 10 }
Defensive patterns

Strategy: validation

Validate before calling

def valid_length_bounds?(length_opts)
  min, max = length_opts.values_at(:min, :max)
  min.nil? || max.nil? || min <= max
end

raise 'length min exceeds max' unless valid_length_bounds?(cfg[:length])

Try / catch

begin
  requires :name, type: String, length: length_cfg
rescue ArgumentError => e
  raise "length bounds from config are inverted: #{e.message}"
end

Prevention

When it happens

Trigger: `requires :name, length: { min: 10, max: 5 }`; bounds sourced from config/env where MAX drifts below MIN in some environment; constants swapped during a refactor.

Common situations: Environment-specific YAML config feeding min and max; copy-paste of another param's length options with only one number updated.

Related errors


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