sprockets: 4.0 error undefined method start_with?

When I run rspec or rails server with sprockets updated to 4.0 I get: undefined method start_with?' for #<Proc:0x00007ffeadf32740> # /Users/jasonhobbs/.rvm/gems/ruby-2.6.5/gems/sprockets-4.0.0/lib/sprockets/uri_utils.rb:78:in valid_asset_uri?’

I have no idea what this is referring to in my code. I had no issues with sprockets 3.7.2

About this issue

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

Commits related to this issue

Most upvoted comments

Just wanted to chime in and let you know that I ran into this same issue when using regexes. I think I found an article somewhere explaining how to add webfonts to the asset pipeline by adding this code to config/initializers/assets.rb

Rails.application.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/

I have now replaced it with the following which fixed the issue for me:

Rails.application.config.assets.precompile << ["*.svg", "*.eot", "*.woff", "*.ttf"]

Downgraded gem sprockets from 4.0.0 to 3.7.2

gem 'sprockets', '~> 3.7.2'

this might help you to investigate

rails c
Rails.application.config.assets.precompile.select{ |path| path.is_a?(Proc) }
=> [#<Proc:0x000000000c320198@/source/init.rb:78>]

it’s an error since https://github.com/rails/sprockets/commit/8c8cccf0f554299f8be85a0b8b2fe4bc23732b4f#diff-56b8a4f4a3946e2ca1750c8580181925L24

I had the same problem here (related to bootstrap).

Installing Bootstrap

I was following the installation guide available in the blog below: https://www.timdisab.com/installing-bootstrap-4-on-rails-6/

Then, I also tried to install the bootstrap using the following ruby bootstrap gems:

gem 'bootstrap-sass'
gem 'bootstrap-generators'
gem 'jquery-rails'

via command below:

bundle install
bundle exec rails generate bootstrap:install

I got the same error

ActionView::Template::Error (undefined method `start_with?' for /\.(?:svg|eot|woff|woff2|ttf)$/:Regexp)

After all, it was not working due to an incorrect gem (sprockets) version.

By downgrading the specific ruby gem (sprockets), the bootstrap was successfully added to my rails-6 project.

Enviroment

ruby ................ 2.7.1
rails ............... 6.0.3.3
gem 'sprockets' ..... 4.0.2

Error

ActionView::Template::Error (undefined method `start_with?' for /\.(?:svg|eot|woff|woff2|ttf)$/:Regexp):

sprockets (4.0.2) lib/sprockets/uri_utils.rb:78:in `valid_asset_uri?'
sprockets (4.0.2) lib/sprockets/resolve.rb:27:in `resolve'
sprockets (4.0.2) lib/sprockets/base.rb:79:in `find_asset'
sprockets (4.0.2) lib/sprockets/base.rb:88:in `find_all_linked_assets'
sprockets (4.0.2) lib/sprockets/manifest.rb:125:in `block (2 levels) in find'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:24:in `block in execute'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `block in synchronize'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:19:in `execute'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/promise.rb:563:in `block in realize'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:363:in `run_task'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:352:in `block (3 levels) in create_worker'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:335:in `loop'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:335:in `block (2 levels) in create_worker'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `catch'
concurrent-ruby (1.1.7) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `block in create_worker'

Solution

Downgrade your sprockets gem in your Gemfile as it was suggested by @cassiopagnoncelli in https://github.com/rails/sprockets/issues/632#issuecomment-559861344

Add the following line to the Gemfile:

gem 'sprockets', '~> 3.7.2'

Then, run the following commands:

bundle update sprockets

bundle exec rake assets:precompile --trace

I just updated the blazer gem in my app to 2.2.1 and it fixed this issue!

I’m getting same error on Rails 6, Rails 5 is fine.

➜ RAILS_ENV=staging bundle exec rake assets:precompile --trace
** Invoke assets:precompile (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke environment (first_time)
** Execute environment
** Invoke yarn:install (first_time)
** Execute yarn:install
** Execute assets:precompile
rake aborted!
NoMethodError: undefined method `start_with?' for /\.(?:svg|eot|woff|ttf)$/:Regexp
/app/.rvm/gems/ruby-2.6.5/gems/sprockets-4.0.0/lib/sprockets/uri_utils.rb:78:in `valid_asset_uri?'
/app/.rvm/gems/ruby-2.6.5/gems/sprockets-4.0.0/lib/sprockets/resolve.rb:27:in `resolve'
/app/.rvm/gems/ruby-2.6.5/gems/sprockets-4.0.0/lib/sprockets/base.rb:79:in `find_asset'
/app/.rvm/gems/ruby-2.6.5/gems/sprockets-4.0.0/lib/sprockets/base.rb:88:in `find_all_linked_assets'
/app/.rvm/gems/ruby-2.6.5/gems/sprockets-4.0.0/lib/sprockets/manifest.rb:125:in `block (2 levels) in find'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/safe_task_executor.rb:24:in `block in execute'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/synchronization/mutex_lockable_object.rb:41:in `block in synchronize'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/safe_task_executor.rb:19:in `execute'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/promise.rb:563:in `block in realize'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:348:in `run_task'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:337:in `block (3 levels) in create_worker'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:320:in `loop'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:320:in `block (2 levels) in create_worker'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in `catch'
/app/.rvm/gems/ruby-2.6.5/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in `block in create_worker'
Tasks: TOP => assets:precompile

Okay in our docs “How Sprockets Work” talk from Rafael. I think this is intentional, but I don’t know why we didn’t deprecate the interface first.


Sprockets has special support for Procs on the precompilation. Before, in Sprockets version 3, we had this code that is telling us to precompile all the known JavaScript and stylesheet files in the app directory.

LOOSE_APP_ASSETS = lambda do |logical_path, filename|
  filename.start_with?(::Rails.root.join('app/assets').to_s) &&
    !['.js', '.css', ''].include?(File.extname(logical_path))
end

config.assets.precompile = [LOOSE_APP_ASSETS, /(?:\/|\\|\A)application\.(.css|js)$/]

As you can see, the code above is not easy to understand, so in Sprockets version 4, we have a new syntax for that shown below:

// app/assets/config/manifest.js
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//= link my_engine

// my_engine/app/assets/config/my_engine.js
//= link_tree ../images/bootstrap

It’s called the link directive, so it’s easier to understand what’s going on there. You can actually see that all the images in the image directory is going to be precompiled just as the JavaScript and the style sheets do. One can use this directive to compose new libraries. I have that link to my engine that’s also defining its own manifest file. It’s now easy to understand and to compose. Not that we are going to remove the precompile list, but these new directives are there to help to build the precompile list. We have all these directives by default in Sprockets and later we will explain how you can extend the directives to create your own.

@Kani999 You have to check 3rd party gems. Some of those are culprit. Check https://github.com/rails/sprockets/issues/632#issuecomment-540032759

@ahorek this was super-helpful. Our instances of this came from PGHero and Searchjoy, not from ActiveAdmin as I had suspected.