When Rubygems gem versioning goes bad

Rubygems, the package manager for Ruby, has long had this neat little functionality to let you specify the version of a gem you want to use, when running a gem-related command. If you have two versions of Rails installed, say versions 4.2.8 and 5.0.2, you can specify which to use by prefixing the command with a specially-formatted version number.

By default Rubygems grabs the latest version installed, so if you ran rails new myapp you would get a Rails 5.0.2 app, but you can override this by saying rails _4.2.8_ new myapp to get a Rails 4.2.8 app instead. (The underscores aren’t a typo, that’s the actual command.) It’s not a feature you’d use every day, but when you need it it’s immensely useful. But someone came into the #rubyonrails channel on IRC today, reporting that this wasn’t working for them. They were trying to create a Rails 5.0.2 app with the proper rails _5.0.2_ new appname command, and were getting a Rails 5.1 app instead. What gives?

After I easily replicated the issue, and Matthew Draper and I investigated the issue (okay, mostly Matthew, but I was moral support!) it turns out that this feature silently broke in Rubygems 2.5.2, which coincidentally both myself and the other user happened to be using. Ohnoes!

To fix the issue is a quick two-step process:

  1. Update Rubygems, with gem update --system. The bug was fixed in version 2.6.2, and this will fetch and install the latest version (2.6.11 at time of writing.)

  2. To rebuild all of the binstubs installed with the buggy version of Rubygems (the binstubs are what provide the versioning functionality), run gem pristine --all --only-executables

And that’s it!

If anything else, it’s a good reminder to keep your Rubygems up to date. Version 2.5.2, the version we were both on, is over a year old now - a long time to go without updates these days!