{"record":{"id":"6a3fd06358df2ed5","repo":"ruby-grape/grape","slug":"is-must-be-an-integer-greater-than-zero","errorCode":null,"errorMessage":"is must be an integer greater than zero","messagePattern":"is must be an integer greater than zero","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/grape/validations/validators/length_validator.rb","lineNumber":16,"sourceCode":"# frozen_string_literal: true\n\nmodule Grape\n  module Validations\n    module Validators\n      class LengthValidator < Base\n        def initialize(attrs, options, required, scope, opts)\n          super\n\n          @min, @max, @is = options.values_at(:min, :max, :is)\n          validate_boundary!(:min, @min)\n          validate_boundary!(:max, @max)\n          raise ArgumentError, \"min #{@min} cannot be greater than max #{@max}\" if @min && @max && @min > @max\n\n          return if @is.nil?\n          raise ArgumentError, 'is must be an integer greater than zero' unless @is.is_a?(Integer) && @is.positive?\n          raise ArgumentError, 'is cannot be combined with min or max' unless @min.nil? && @max.nil?\n        end\n\n        def validate_param!(attr_name, params)\n          return unless hash_like?(params)\n\n          param = params[attr_name]\n\n          return unless param.respond_to?(:length)\n\n          return unless (!@min.nil? && param.length < @min) || (!@max.nil? && param.length > @max) || (!@is.nil? && param.length != @is)\n\n          validation_error!(attr_name, message do\n            if @min && @max\n              translate(:length, min: @min, max: @max)\n            elsif @min\n              translate(:length_min, min: @min)\n            elsif @max","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/ruby-grape/grape/blob/22d7975629846a3c0c7bd2b34e140a7a1b4af8f6/lib/grape/validations/validators/length_validator.rb#L1-L34","documentation":"`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.","triggerScenarios":"`length: { is: 0 }`; `length: { is: -3 }`; `length: { is: '4' }` (string from env/config); `length: { is: 2.5 }` (float).","commonSituations":"Env-var or config values arriving as strings and passed through unconverted; intending 'optional, at most N' and reaching for `is: 0`.","solutions":["Use a positive Integer: `length: { is: 5 }`","Coerce config-sourced values before use: `is: cfg.fetch(:is).to_i` and reject non-positive results","If you meant 'at most N' rather than 'exactly N', use `max:` instead of `is:`"],"exampleFix":"# before\nrequires :code, type: String, length: { is: '4' }\n\n# after\nrequires :code, type: String, length: { is: 4 }","handlingStrategy":"validation","validationCode":"def valid_is?(length_opts)\n  is = length_opts[:is]\n  is.nil? || (is.is_a?(Integer) && is.positive?)\nend\n\nraise 'length is: must be a positive Integer' unless valid_is?(cfg[:length])","typeGuard":null,"tryCatchPattern":"begin\n  requires :code, type: String, length: { is: cfg_value }\nrescue ArgumentError => e\n  raise \"length is: rejected (#{cfg_value.inspect}) — pass a positive Integer: #{e.message}\"\nend","preventionTips":["Coerce env/config strings with `.to_i` before they reach the DSL","Use `max:` when you mean 'at most N', `min:` for 'at least N' — `is:` only for exact lengths","Spec-test config-to-DSL plumbing for length rules"],"tags":["grape","params","length-validation","argumenterror","config"],"backgroundTag":"invalid-constraint-value","analyzedSha":"22d7975629846a3c0c7bd2b34e140a7a1b4af8f6","analyzedAt":"2026-08-21T17:03:54.627Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}