ruby-on-railsruby-on-rails-5.1actiondispatch

Rails 5.1: "unknown firstpos: NilClass" - Issue reloading application


enter image description here

Following an upgrade from Rails 5.0 to 5.1 I'm getting this error anytime the app reloads, either from code changes during rails server or if I call reload! from the console.

🌶 13:53$ rc
Loading development environment (Rails 5.1.1)
2.3.1 :001 > reload!
Reloading...
ArgumentError: unknown firstpos: NilClass
    from (irb):1
2.3.1 :002 > 

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/journey/gtg/builder.rb

Application Trace is empty, here's the Framework Trace:

actionpack (5.1.1) lib/action_dispatch/journey/gtg/builder.rb:99:in `firstpos'
actionpack (5.1.1) lib/action_dispatch/journey/gtg/builder.rb:22:in `transition_table'
actionpack (5.1.1) lib/action_dispatch/journey/routes.rb:58:in `simulator'
actionpack (5.1.1) lib/action_dispatch/journey/router.rb:92:in `simulator'
actionpack (5.1.1) lib/action_dispatch/journey/router.rb:28:in `eager_load!'
actionpack (5.1.1) lib/action_dispatch/routing/route_set.rb:382:in `eager_load!'
railties (5.1.1) lib/rails/application/routes_reloader.rb:26:in `each'
railties (5.1.1) lib/rails/application/routes_reloader.rb:26:in `execute'
railties (5.1.1) lib/rails/application/finisher.rb:141:in `block (2 levels) in <module:Finisher>'
activesupport (5.1.1) lib/active_support/callbacks.rb:413:in `instance_exec'
activesupport (5.1.1) lib/active_support/callbacks.rb:413:in `block in make_lambda'
activesupport (5.1.1) lib/active_support/callbacks.rb:197:in `block (2 levels) in halting'
activesupport (5.1.1) lib/active_support/callbacks.rb:601:in `block (2 levels) in default_terminator'
activesupport (5.1.1) lib/active_support/callbacks.rb:600:in `catch'
activesupport (5.1.1) lib/active_support/callbacks.rb:600:in `block in default_terminator'
activesupport (5.1.1) lib/active_support/callbacks.rb:198:in `block in halting'
activesupport (5.1.1) lib/active_support/callbacks.rb:507:in `block in invoke_before'
activesupport (5.1.1) lib/active_support/callbacks.rb:507:in `each'
activesupport (5.1.1) lib/active_support/callbacks.rb:507:in `invoke_before'
activesupport (5.1.1) lib/active_support/callbacks.rb:130:in `run_callbacks'
activesupport (5.1.1) lib/active_support/execution_wrapper.rb:108:in `run!'
activesupport (5.1.1) lib/active_support/reloader.rb:113:in `run!'
activesupport (5.1.1) lib/active_support/execution_wrapper.rb:70:in `block in run!'
activesupport (5.1.1) lib/active_support/execution_wrapper.rb:67:in `tap'
activesupport (5.1.1) lib/active_support/execution_wrapper.rb:67:in `run!'
activesupport (5.1.1) lib/active_support/reloader.rb:59:in `run!'
actionpack (5.1.1) lib/action_dispatch/middleware/executor.rb:10:in `call'
actionpack (5.1.1) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
actionpack (5.1.1) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.1.1) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.1.1) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.1.1) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.1.1) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.1.1) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.1.1) lib/rails/rack/logger.rb:24:in `call'
sprockets-rails (3.2.0) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.1.1) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
request_store (1.3.2) lib/request_store/middleware.rb:9:in `call'
actionpack (5.1.1) lib/action_dispatch/middleware/request_id.rb:25:in `call'
rack (2.0.3) lib/rack/method_override.rb:22:in `call'
rack (2.0.3) lib/rack/runtime.rb:22:in `call'
activesupport (5.1.1) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
actionpack (5.1.1) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.1) lib/action_dispatch/middleware/static.rb:125:in `call'
rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
railties (5.1.1) lib/rails/engine.rb:522:in `call'
puma (3.9.1) lib/puma/configuration.rb:224:in `call'
puma (3.9.1) lib/puma/server.rb:602:in `handle_request'
puma (3.9.1) lib/puma/server.rb:435:in `process_client'
puma (3.9.1) lib/puma/server.rb:299:in `block in run'
puma (3.9.1) lib/puma/thread_pool.rb:120:in `block in spawn_thread'

Solution

  • Workaround found! https://github.com/rails/rails/pull/32296

    The pull request is not merged, and will probably only be in 5.2+ anyway. Adding a monkey patch with the one-line change fixed the problem entirely for me.

    config/initializers/routes.rb

    # MONKEY PATCH!!!
    # https://github.com/rails/rails/pull/32296
    #
    # Fixes:
    # * Development mode deadlocks
    # * ArgumentError: unknown firstpos: NilClass
    #
    # Allows use of "config.eager_load = true"
    
    
    module ActionDispatch
      module Journey
        class Routes
          def simulator
            @simulator ||= begin
              gtg = GTG::Builder.new(ast).transition_table unless ast.blank?
              GTG::Simulator.new(gtg)
            end
          end
        end
      end
    end