21

I'm getting the following error after upgrading to Rails 4:

.../ruby-1.9.3-p125/gems/actionpack-4.0.0.rc2/lib/action_dispatch/middleware/stack.rb:125:in 'assert_index': No such middleware to insert before: Rack::Lock (RuntimeError)

The offending line is my "remove slashes" rack-rewrite rule:

config.middleware.insert_before(Rack::Lock, Rack::Rewrite) do
  r301 %r{^/(.*)/$}, '/$1', :headers => {'Cache-Control' => 'public, max-age='+2.week.to_s}
end

Any ideas?

Community
  • 1
  • 1
William Denniss
  • 16,089
  • 7
  • 81
  • 124

1 Answers1

42

As the error suggests ("No such middleware to insert before"), the issue is with the middleware you are trying to insert before (and not the middleware you are trying to insert, which was my initial assumption).

In Rails4, threading is enabled by default which removes Rack::Lock.

To find a replacement, you can run rake middleware from your rails project directory, and look for something near the start of the stack. I'm going to pick Rack::Runtime as it is early in the stack, and seems pretty standard.

So the rewrite config is now:

config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
  r301 %r{^/(.*)/$}, '/$1', :headers => {'Cache-Control' => 'public, max-age='+2.week.to_s}
end
William Denniss
  • 16,089
  • 7
  • 81
  • 124
  • 3
    Just one thing that confused me for a while was `rake middleware` was returning the full list of expected middleware including `Rack::Lock` and yet my rspec tests were failing due to not finding `Rack::Lock`. In the end I realised (by inspecting config.middleware directly) that rspec was of course not loading the full stack of middleware. I therefore moved the rewrites to `config/environments/production.rb` as I wouldn't be testing these redirects in rspec anyway. – Stefan Magnuson Feb 05 '14 at 07:02
  • Thanks for figuring this out! The resource you're linking to in your answer no longer exists unfortunately. – Aaron Feb 09 '16 at 16:18
  • In my case I needed to put `config.middleware.insert_before Rack::Runtime, Rack::LiveReload`, which may be specifically for Rails >=6. [Details are here in the `rack-livereload` README](https://github.com/jaredmdobson/rack-livereload#rails) – floer32 Mar 02 '21 at 07:13