Search code examples
ruby-on-railsrubyrspecraketravis-ci

TypeError: superclass mismatch for class Task


I have a Rails project and use RSpec for testing. Recently, I added this in my spec_helper.rb:

config.before(:suite) do
  Rails.application.load_tasks
end

If I run the tests locally with bundle exec rspec, everything is fine. But when I try to do the same thing on Travis CI, the command crashes with:

TypeError: superclass mismatch for class Task
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/task.rb:9:in `<module:Rails>'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/task.rb:8:in `<module:Sprockets>'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/task.rb:7:in `<top (required)>'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:274:in `require'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:274:in `block in require'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:274:in `require'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.1/lib/sprockets/railtie.rb:163:in `block in <class:Railtie>'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:237:in `instance_exec'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:237:in `block in run_tasks_blocks'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:245:in `each'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:245:in `each_registered_block'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:237:in `run_tasks_blocks'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/application.rb:451:in `block in run_tasks_blocks'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/engine/railties.rb:13:in `each'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/engine/railties.rb:13:in `each'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/application.rb:451:in `run_tasks_blocks'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/engine.rb:453:in `load_tasks'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:194:in `public_send'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/railtie.rb:194:in `method_missing'
    from (irb):25
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/commands/console.rb:110:in `start'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/commands/console.rb:9:in `start'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/commands/commands_tasks.rb:68:in `console'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/railties-4.2.9/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

The same thing happens if I debug the Travis build and manually start a bundle exec rails c and do a Rails.application.load_tasks.

What could possibly be the problem here? Any clue would be highly appreciated!


Solution

  • TypeError: superclass mismatch happens when you reopen a class and try to redefine the superclass for it. This is a way to force this error:

    class A; end
    class B < A; end
    class C; end
    class B < C; end # raises error
    

    Since this only happens on Travis environment, I'd debug it right there if possible:

    • Open /home/travis/build/my_application/vendor/bundle/ruby/2.3.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/task.rb with vim nano or similar CLI editor
    • put require 'pry'; binding.pry, above the line that causes the error
    • bundle install
    • rerun your testing code
    • get in the debugger and inspect where is Task coming from. Since you are getting TypeError: superclass mismatch, Task must have been defined before this line that's reopening it. show-source Task should show you where it was defined.