{"record":{"id":"0df78deb5fe0d042","repo":"ruby-grape/grape","slug":"name-must-be-an-integer-greater-than-or-equal-t","errorCode":null,"errorMessage":"#{name} must be an integer greater than or equal to zero","messagePattern":"#(.+?) must be an integer greater than or equal to zero","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/grape/validations/validators/length_validator.rb","lineNumber":45,"sourceCode":"          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\n              translate(:length_max, max: @max)\n            else\n              translate(:length_is, is: @is)\n            end\n          end)\n        end\n\n        private\n\n        def validate_boundary!(name, val)\n          raise ArgumentError, \"#{name} must be an integer greater than or equal to zero\" if !val.nil? && (!val.is_a?(Integer) || val.negative?)\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":27,"sourceCodeEnd":51,"githubUrl":"https://github.com/ruby-grape/grape/blob/22d7975629846a3c0c7bd2b34e140a7a1b4af8f6/lib/grape/validations/validators/length_validator.rb#L27-L51","documentation":"Each `min:`/`max:` bound passed to the `length` validator must be a non-negative Integer (`validate_boundary!`). Negative numbers and non-integers (strings, floats) are rejected with ArgumentError at definition time — these are declaration bugs, not per-request validation failures.","triggerScenarios":"`length: { min: -1 }`; `length: { max: '10' }` (string from env/config); `length: { min: 3.5 }` (float).","commonSituations":"ENV-sourced bounds passed as strings without conversion; floats copied in from calculators or other validator configs.","solutions":["Pass non-negative Integers: `length: { min: 2, max: 10 }`","Convert config-sourced values before the DSL sees them: `min: cfg[:min].to_i` and clamp negatives","Omit the key entirely rather than passing 0 when no lower bound is wanted"],"exampleFix":"# before\nrequires :bio, type: String, length: { min: '10', max: 500 }\n\n# after\nrequires :bio, type: String, length: { min: 10, max: 500 }","handlingStrategy":"validation","validationCode":"def valid_bound?(value)\n  value.nil? || (value.is_a?(Integer) && !value.negative?)\nend\n\ndef valid_length_boundaries?(length_opts)\n  valid_bound?(length_opts[:min]) && valid_bound?(length_opts[:max])\nend","typeGuard":null,"tryCatchPattern":"begin\n  requires :bio, type: String, length: { min: cfg[:min], max: cfg[:max] }\nrescue ArgumentError => e\n  raise \"length bounds must be non-negative Integers: #{e.message}\"\nend","preventionTips":["Convert ENV/config bounds with `.to_i` and reject negatives before the DSL sees them","Omit a bound key rather than passing 0 to mean 'unbounded'","Keep length rules in one place per endpoint instead of scattering partial configs"],"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"}