OS X Mavericks RubyGems cleanup issue

Ever tried sudo gem cleanup in OS X Mavericks only to be hit with errors like this?

Attempting to uninstall sqlite3-1.3.7
Unable to uninstall sqlite3-1.3.7:
  Gem::InstallError: sqlite3 is not installed in GEM_HOME, try:
  gem uninstall -i /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0 sqlite3

Google is a bit of a let down here, but don’t worry, there is an easier workaround than individually uninstalling each outdated gem as the error message suggests. Luckily there are a few ancient posts (like this one) describing the same issue in older versions of OS X and with a few tweaks the fix still works.

Disclaimer

The “correct” answer to this problem is to not use the system RubyGems in the first place in favour of something like RVM. I have my reasons for not doing that this time and you probably do too. I am not a Terminal/Ruby guru, the following is my best understanding and what has worked for me.

Cause

Ruby gems can be installed in 3 locations and gem cleanup does not look in all of them. Try gem environment and take a look at the GEM PATHS list. Mine looks like this:

  - GEM PATHS:
     - /Library/Ruby/Gems/2.0.0
     - /Users/jaydenseric/.gem/ruby/2.0.0
     - /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0

Some gems start their life in the OS X default location in /System/.... Their updated versions however automatically get placed in /Library/... or /Users/... depending if you used sudo gem update or just gem update. New gems you add yourself don’t get placed in the /System/... location and should not be problematic.

Solution

A nice workaround is to temporarily get gem cleanup to also look in the /System/... location. Once the outdated and awkwardly stored gems are removed from there everything should live happily ever after. Following a problematic sudo gem update, use:

sudo sh -c 'GEM_HOME=/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0 gem cleanup'

You will need to repeat this every time gems in /System/... are updated until they have all been moved.