Adventures in Debugging the Asset Pipeline

Let's talk about software versioning.

I spent a large chunk of time debugging a strange issue on behalf of a customer. This customer had a Rails stack with three web servers, and wished to scale up a fourth one.

The assets were being compiled on the server itself. However, a subset of the compiled assets on this new server had a different MD5 hash appended to the filename - when you precompile your assets, Rails will append an MD5 hash of the file to the end of the filename in order to differentiate it from previous versions of the assets.

Here are just a small selection of things I considered when resolving this issue:

  • Git checked out the wrong version of the code (nope)
  • Different versions of Ruby Gems installed (also not the case)
  • Different version of MD5 hasher (can't be the case since only a subset of assets was affected)
  • Quantum server wave function collapse (unverified)

In the end, I had to find the original files that the precompiled assets were referring to and see if they had anything in common. Luckily enough, they did!

When all was said and done, the culprit was a Ruby Gem that provided some assets to the customer's Rails application (not pointing any fingers - consider this my Valentine's day present to you, dear Gem author). This is a possibility I had not considered because... the same version was installed on both servers!

Here is a timeline of the events that must have taken place:

  • Author releases Gem version 0.4.2 - this version is correct. This is the version installed on the customer's original three servers.
  • Some voodoo magic happens, as a result of which the released 0.4.2 version becomes different. Specifically, it is now missing the app/assets/javascripts directory.
  • Instead of correcting voodoo magic, author keeps the broken version online, and releases version 0.4.2-whoopsa-daisy, which now contains the missing app/assets/javascripts directory.
  • Customer scales up a web server with Gem version 0.4.2 - this is now different from the 0.4.2 on the other three servers. Bundler cannot tell the difference in Gem contents - only in version. Lo and behold - the assets hashes are different.

So much for my quantum computer discovery.

And so, we come full circle to software versioning. If you have come this far - I have but one request.

Please, please, please remember that as soon as you publish a specific version of your application online, people will be using that version with the assumption that the contents of this version are set in stone!

If the code you published is in some way broken, the correct action is to publish a fix with a bumped version; and if the old version is so broken that it warrants unpublishing, to remove all traces of it. It will then be obvious to people that previously downloaded that version that it is no longer valid.