Today I made a very small change to an app and then deployed it to Heroku.  After the deploy was complete I visited the app and was presented with an error page.  The error message in the logs let me know that application.css was not compiled, but I couldn’t figure out why.  Here’s what I did to break my app, and what I did to track down the issue.

The breaking change

I was installing the heroku_san gem to make deploying to heroku more of a streamlined process. (I miss the deploy hooks from capistrano, and heroku_san offers a similar mechanism.) I added the heroku_san gem to my :development, :test group in the Gemfile, and since my project doesn’t use a regular database I needed to alter the deploy strategy. So, I added this to one of my rake files:

 require 'heroku_san'
HerokuSan.project = HerokuSan::Project.new(Rails.root.join("config","heroku.yml"), :deploy => HerokuSan::Deploy::Sinatra)

Then I deployed the app, and went to take a look. That’s when I got the error page, and had to start digging.

First I ran heroku logs to see what was going on. Here’s the bit that stood out.

2013-02-06T03:19:51+00:00 app[web.1]: Completed 500 Internal Server Error in 144ms
2013-02-06T03:19:52+00:00 app[web.1]: 
2013-02-06T03:19:52+00:00 app[web.1]: ActionView::Template::Error (application.css isn't precompiled)

Hmmm…. Why would application.css not be precompiled? I took at look at the output from the last deploy, and I couldn’t find any trace of the asset:precompile step having happened. Here’s the last bit of the deploy output:

...
       Your bundle is complete! It was installed into ./vendor/bundle
       Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Rails plugin injection
       Injecting rails_log_stdout
       Injecting rails3_serve_static_assets
-----> Discovering process types
       Procfile declares types      -> web
       Default types for Ruby/Rails -> console, rake, worker
-----> Compiled slug size: 18.6MB
-----> Launching... done, v14

There should have been a step for assets:precompile right after the step for writing the database config file.

Wondering if it was a fluke, I made a tiny change and pushed again. Still no dice.

Investigation

To figure out what was going on I connected directly to a heroku dyno and tried to compile the assets by hand.

$ heroku run bash --app wholesaler-tool-staging
Running `bash` attached to terminal... up, run.xxx
~ $ bundle exec rake assets:precompile
rake aborted!
no such file to load -- heroku_san

Ah-ha! Of course, when any rake task is run, all of the rake tasks have to be loaded. Since heroku_san is not in the gem set for production it can’t be loaded. It would be nice if heroku would surface this error during the deploy instead of allowing it to go past silently.

Anyhoo, I made a quick change to that rake file to wrap the heroku_san stuff in a conditional.

unless Rails.env.production? 
  require 'heroku_san'
  HerokuSan.project = HerokuSan::Project.new(Rails.root.join("config","heroku.yml"), :deploy => HerokuSan::Deploy::Sinatra)
end

I committed the change and deployed again and everything was back to normal.