When a String Assumption Broke Newsletter Tag Filtering in Ruby
An in-depth look at fixing a NoMethodError in RubyEvents when tags are not strings.

Stock photo for illustration only, not from the actual event
- Production bugs do not always require hundreds of lines of code.
- Calling downcase on integers causes immediate application crashes.
- Using to_s and casecmp? provides a robust and resilient solution.
- Switching to any? aligns the code closer to its actual intent.
A software bug does not always need hundreds of lines of code to trigger a severe issue in production. That exact scenario lived quietly inside a Ruby filtering method within the open-source RubyEvents project, operating seamlessly until a non-string tag entered the system.
That minor mismatch was enough to turn a standard user interaction into an unexpected application error. This is the story of how the developer tracked down the underlying root cause and successfully resolved it.
At a glance, the failure might easily be mistaken for a routing or controller issue. However, the root cause resided deeper within the tag-filtering logic, specifically inside the Announcement::Collection#by_tag method, which originally assumed all incoming tags were strictly strings.

Stock photo for illustration only, not from the actual event
Data type assumptions are a classic pitfall in software engineering, particularly in dynamically typed languages like Ruby. While flexibility is a primary benefit, failing to validate data boundaries frequently leads to runtime failures when unexpected data structures flow through production environments.
For standard string values, the original implementation executed flawlessly. However, when an array containing mixed types such as [ "Ruby" , 123 ] was processed alongside map(&:downcase), the runtime attempted to execute 123.downcase, triggering an error because integers do not possess a downcase method.
The appropriate fix was not to alter data sources universally, but rather to make the comparison resilient. By explicitly converting values using to_s, leveraging casecmp? for case-insensitive checks, and refactoring the collection traversal to use any?, the code became both safer and more expressive.
Source: Dev.to
Found something wrong in this article? Report an issue with this article
Comments
Leave a Comment