ruby-grape/grape · error · ArgumentError

is must be an integer greater than zero

Error message

is must be an integer greater than zero

What it means

`length: { is: N }` requires an exact length, so N must be a positive Integer: zero or negative lengths are impossible, and non-integers (strings, floats) cannot be compared reliably against `#length`. The LengthValidator raises ArgumentError at definition time otherwise.

Source

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

# 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

View on GitHub (pinned to 22d7975629)

Solutions

  1. Use a positive Integer: `length: { is: 5 }`
  2. Coerce config-sourced values before use: `is: cfg.fetch(:is).to_i` and reject non-positive results
  3. If you meant 'at most N' rather than 'exactly N', use `max:` instead of `is:`

Example fix

# before
requires :code, type: String, length: { is: '4' }

# after
requires :code, type: String, length: { is: 4 }
Defensive patterns

Strategy: validation

Validate before calling

def valid_is?(length_opts)
  is = length_opts[:is]
  is.nil? || (is.is_a?(Integer) && is.positive?)
end

raise 'length is: must be a positive Integer' unless valid_is?(cfg[:length])

Try / catch

begin
  requires :code, type: String, length: { is: cfg_value }
rescue ArgumentError => e
  raise "length is: rejected (#{cfg_value.inspect}) — pass a positive Integer: #{e.message}"
end

Prevention

When it happens

Trigger: `length: { is: 0 }`; `length: { is: -3 }`; `length: { is: '4' }` (string from env/config); `length: { is: 2.5 }` (float).

Common situations: Env-var or config values arriving as strings and passed through unconverted; intending 'optional, at most N' and reaching for `is: 0`.

Related errors


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