sprockets: Sprockets is raising Sprockets::FileNotFound for image assets that do exist

Expected behavior

Assets should compile successfully.

Actual behavior

Assets are failing to compile on Heroku due to a Sprockets::FileNotFound error being raised. This seems to only happen on Heroku and does not happen locally (even when run locally with the staging or production environments set).

It only ever fails with images. Here is what our manifest.js looks like regarding images:

//= link_tree ./../images .gif
//= link_tree ./../images .jpg
//= link_tree ./../images .jpeg
//= link_tree ./../images .png

This sort of error was sporadically happening last week with it failing to find 2 different image files that were not used in any SCSS (they were old images). Removing the image files seemed to remedy the problem and precompiling worked for dozens of subsequent builds. Changes within these subsequent builds included changes to both assets and unrelated application code.

For his particular error, the image is used in our SCSS so removing it is not an option. It’s almost like once an asset file is not found during precompile, all subsequent deploys will continue to fail until we remove the image file.

I wonder if caching has something to do with it? Is there a way to disable caching entirely for the precompile process? We are not setting any cache options explicitly and I believe the Null cache store is being used but maybe I am wrong…

System configuration

  • sprockets-d22a4ea9c226 (current master)
  • Ruby version 2.3.3

Backtrace

remote: -----> Preparing app for Rails asset pipeline
remote:        Running: rake assets:precompile
remote:        rake aborted!
remote:        Sprockets::FileNotFound: could not find file: /tmp/build_e296f6ae4c88324c54640ff593770ab9/app/assets/images/lightbox-spinner.gif
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:102:in `load_from_unloaded'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:59:in `block in load'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:318:in `fetch_asset_from_dependency_cache'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:43:in `load'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/cached_environment.rb:44:in `load'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/bundle.rb:32:in `block in call'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/bundle.rb:31:in `call'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/processor_utils.rb:84:in `call_processor'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/processor_utils.rb:66:in `block in call_processors'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/processor_utils.rb:65:in `reverse_each'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/processor_utils.rb:65:in `call_processors'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:144:in `load_from_unloaded'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:59:in `block in load'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:318:in `fetch_asset_from_dependency_cache'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/loader.rb:43:in `load'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/cached_environment.rb:44:in `load'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/base.rb:69:in `find_asset'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/base.rb:76:in `find_all_linked_assets'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/manifest.rb:124:in `block in find'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/manifest.rb:123:in `each'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/manifest.rb:123:in `find'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/sprockets/manifest.rb:165:in `compile'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.0/lib/sprockets/rails/task.rb:68:in `block (3 levels) in define'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/bundler/gems/sprockets-5f525cd589f8/lib/rake/sprocketstask.rb:148:in `with_logger'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.0/lib/sprockets/rails/task.rb:67:in `block (2 levels) in define'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/gems/airbrake-5.6.1/lib/airbrake/rake/task_ext.rb:19:in `execute'
remote:        /tmp/build_2f0fd9dfd7094d9363b61deccaaa6e1f/vendor/bundle/ruby/2.3.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 27 (7 by maintainers)

Most upvoted comments

Just wanted to say that we have the exact same issue on our end (only happens on Heroku) Running precompilation locally in production env works just fine.

I really dislike spring.

For that code you can use a Proc or Lambda so that you only need the value when you’re actually using it.

I wouldn’t recommend using config.assets.compile in production. It’s very slow.

Ok we found the issue

in our model we have something like

class User < ApplicationRecord
  CONSTANT = ActionController::Base.helpers.asset_path('missing_screenshot.png')
end

When you have no assets, no cache

$ rm -rf public/assets
$ rm -rf tmp/cache

Any rake command like RAILS_ENV=production rake assets:clobber or RAILS_ENV=production rake assets:precompile will load the constant and because you don’t have the asset it will break.

Few options

  • Don’t use a call to asset_path when class are loaded before assets calls.
  • set config.assets.compile to true (# Do not fallback to assets pipeline if a precompiled asset is missed.)