Fix LengthValidator crash with proc minimum and nil value
From uloza+hey@proton.me · original ↗ · unsubscribe
The proc was resolved only when the value was present, so for a nil value it leaked unresolved into the error message and was invoked with the message options hash instead of the record. It is now resolved before the error is built, producing the expected “is too short” message.
Fix LengthValidator crash with proc minimum and nil value by ousamabenyounes · Pull Request #58428 · rails/rails · GitHub
Navigation Menu
Appearance settings
-
Platform
-
AI CODE CREATION
-
DEVELOPER WORKFLOWS
-
APPLICATION SECURITY
-
EXPLORE
-
-
Solutions
-
BY COMPANY SIZE
-
BY USE CASE
-
BY INDUSTRY
-
-
Resources
-
EXPLORE BY TOPIC
-
EXPLORE BY TYPE
-
SUPPORT & SERVICES
-
-
Open Source
-
COMMUNITY
-
PROGRAMS
-
REPOSITORIES
-
-
Enterprise
Search/
Appearance settings
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert
Uh oh!
There was an error while loading. Please reload this page.
- Notifications You must be signed in to change notification settings
- Fork 22.4k
- Code
- Issues 485
- Pull requests 1.1k
- Discussions
- Actions
- Security and quality 26
- Insights
Additional navigation options
Fix LengthValidator crash with proc minimum and nil value - #58428
#58428
Merged
kamipo merged 1 commit into
rails:mainrails/rails:mainfrom
ousamabenyounes:fix/issue-40642ousamabenyounes/rails:fix/issue-40642Copy head branch name to clipboard
Aug 10, 2026
ConversationCommits1 (1)ChecksFiles changed
Merged
##
Fix LengthValidator crash with proc minimum and nil value#58428
kamipo merged 1 commit into
rails:mainrails/rails:mainfrom
ousamabenyounes:fix/issue-40642ousamabenyounes/rails:fix/issue-40642Copy head branch name to clipboard
Conversation
###
ousamabenyounes commented Aug 10, 2026
Copy link
Copy Markdown
Contributor
Motivation / Background
Fixes #40642.
LengthValidator raises NoMethodError when a :minimum (or :is) length
constraint is given as a proc and the validated value is nil:
class Foo include ActiveModel::Validations validates :bar, length: { minimum: ->(record) { record.one + 2 } } def one = 1 def bar = nil end
Foo.new.errors.messages # => NoMethodError: undefined method ‘one’ for an instance of Hash
The proc was resolved (resolve_value) only inside the branch guarded by the
value being present:
if !value.nil? || skip_nil_check?(key) check_value = resolve_value(record, check_value) … end errors_options[:count] = check_value
skip_nil_check? is only true for :maximum, so for a nil value with a
:minimum/:is proc the branch is skipped and the raw proc is stored in
errors_options[:count]. It then leaks into I18n interpolation and is invoked
with the message options hash instead of the record, raising NoMethodError.
Detail
Resolve the check value once, before the error is built, so :count is always
a concrete value. Currently-working paths are unchanged: resolve_value is
idempotent for concrete integers, and the proc is still invoked exactly once
per check. (Symbols were already resolved correctly downstream and are not
affected.)
CHECKS.each do |key, validity\_check|
next unless check\_value = options\[key\]
- check_value = resolve_value(record, check_value) + if !value.nil? || skip_nil_check?(key) - check_value = resolve_value(record, check_value) next if value_length.public_send(validity_check, check_value) end
Additional information
Test verification (RED → GREEN)
Two regression tests were added (proc as :minimum and as :is, both with a
nil value).
RED — activemodel/lib/active_model/validations/length.rb at its unmodified
main state, with only the new tests applied:
Error:
LengthValidationTest#test_validates_length_of_using_proc_as_minimum_with_nil_value:
NoMethodError: undefined method 'min_title_length' for an instance of Hash
Error:
LengthValidationTest#test_validates_length_of_using_proc_as_is_with_nil_value:
NoMethodError: undefined method 'exact_title_length' for an instance of Hash
43 runs, 295 assertions, 0 failures, 2 errors, 0 skips
GREEN — with the fix applied (full Active Model suite):
1197 runs, 5378 assertions, 0 failures, 0 errors, 0 skips
Checklist
- This Pull Request is related to one change.
- Commit message has a detailed description of what changed and why.
- Tests are added or updated if you fix a bug or add a feature.
- CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
[Fix LengthValidator crash with proc minimum and nil value](/rails/rails/pull/58428/commits/9096675dffaa225b2a321658d17f12b494c191b3 "Fix LengthValidator crash with proc minimum and nil value [Fix #40642] When a length constraint (:minimum or :is) was given as a proc, resolve_value was only called inside the branch guarded by the value being present. For a nil value with a :minimum (or :is) constraint the raw proc leaked unresolved into errors_options[:count] and was later invoked with the message options hash during I18n interpolation, raising NoMethodError instead of producing the expected \"is too short\" message. Resolve the check value once, before building the error, so the error message always receives a concrete count. Currently-working paths are unchanged since resolve_value is idempotent for concrete integers and the proc is still invoked exactly once per check.") …
[9096675](/rails/rails/pull/58428/commits/9096675dffaa225b2a321658d17f12b494c191b3)
[Fix rails#40642]
When a length constraint (:minimum or :is) was given as a proc, resolve_value was only called inside the branch guarded by the value being present. For a nil value with a :minimum (or :is) constraint the raw proc leaked unresolved into errors_options[:count] and was later invoked with the message options hash during I18n interpolation, raising NoMethodError instead of producing the expected “is too short” message.
Resolve the check value once, before building the error, so the error message always receives a concrete count. Currently-working paths are unchanged since resolve_value is idempotent for concrete integers and the proc is still invoked exactly once per check.
github-actions Bot added the activemodel label Aug 10, 2026
Hide details View details
kamipo merged commit e137505 into rails:main Aug 10, 2026
5 checks passed
Uh oh!
There was an error while loading. Please reload this page.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
### Reviewers
No reviews
Assignees
No one assigned
Labels
Projects
None yet
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
LenthValidator breaks if nil value has a minimum length with a proc.
Uh oh!
There was an error while loading. Please reload this page.
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Footer
Footer navigation
- Terms
- Privacy
- Security
- Status
- Community
- Docs
- Contact
- Manage cookies
- Do not share my personal information
You can’t perform that action at this time.