Home > Mobile >  Sorbet `srb init` fails with Kernel#exit due to conflict with yard gem
Sorbet `srb init` fails with Kernel#exit due to conflict with yard gem

Time:09-16

We're starting to use Sorbet at work and srb init throws an error requiring yard. Files still generated and seemed to work fine until srb tc started to produce errors like the following:

sorbet/rbi/todo.rbi:38: PG::Error was previously defined as a class https://srb.help/4012
    38 |module PG::Error; end
        ^^^^^^^^^^^^^^^^
    sorbet/rbi/hidden-definitions/hidden.rbi:121092: Previous definition
      121092 |class PG::Error
              ^^^^^^^^^^^^^^^

Re-generating the hidden definitions with bundle exec srb rbi hidden-definitions produced the same error as srb init, and neither one fixes the problem. It seemed worthwhile to get to the bottom of the error in order to ensure our sorbet files are generating correctly.

With: Ruby 2.6.5, Rails 6.1.4.1, Sorbet 0.5.9115, Yard 0.9.26

Steps to reproduce:

gem install rails
rails new srb_yard_test
cd srb_yard_test

Add the following to the Gemfile

gem 'yard'
gem 'sorbet', :group => :development
gem 'sorbet-runtime'
bundle install
bundle exec srb init

Snippet from the srb init output:

Naming YARD::Handlers::Ruby::Legacy/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/parser/ruby/legacy/irb/slex.rb:18: warning: already initialized constant IRB::SLex::DOUT
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/2.6.0/irb/slex.rb:24: warning: previous definition of DOUT was here
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/parser/ruby/legacy/irb/slex.rb:19: warning: already initialized constant IRB::SLex::D_WARN
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/2.6.0/irb/slex.rb:25: warning: previous definition of D_WARN was here
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/parser/ruby/legacy/irb/slex.rb:20: warning: already initialized constant IRB::SLex::D_DEBUG
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/2.6.0/irb/slex.rb:26: warning: previous definition of D_DEBUG was here
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/parser/ruby/legacy/irb/slex.rb:21: warning: already initialized constant IRB::SLex::D_DETAIL
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/2.6.0/irb/slex.rb:27: warning: previous definition of D_DETAIL was here
Naming YARD::Server::CommandsKernel#exit was called while requiring ruby source files
Traceback (most recent call last):
    61: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/bin/srb-rbi:237:in `<main>'
    60: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/bin/srb-rbi:196:in `main'
    59: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/bin/srb-rbi:121:in `init'
    58: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/bin/srb-rbi:232:in `block in make_step'
    57: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/hidden-definition-finder.rb:38:in `main'
    56: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/hidden-definition-finder.rb:44:in `main'
    55: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/hidden-definition-finder.rb:75:in `all_modules_and_aliases'
    54: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/hidden-definition-finder.rb:68:in `constant_cache'
    53: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/gem-generator-tracepoint/tracer.rb:40:in `new'
    52: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/gem-generator-tracepoint/tracer.rb:40:in `new'
    51: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:70:in `initialize'
    50: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:211:in `dfs_module'
    49: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:211:in `each'
    48: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:212:in `block in dfs_module'
    47: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:211:in `dfs_module'
    46: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:211:in `each'
    45: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:212:in `block in dfs_module'
    44: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:211:in `dfs_module'
    43: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:211:in `each'
    42: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:212:in `block in dfs_module'
    41: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:145:in `dfs_module'
    40: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:145:in `each'
    39: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/constant_cache.rb:157:in `block in dfs_module'
    38: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/real_stdlib.rb:77:in `real_const_get'
    37: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/real_stdlib.rb:77:in `call'
    36: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/real_stdlib.rb:77:in `const_get'
    35: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
    34: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
    33: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
    32: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
    31: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
    30: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
    29: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/frames_command.rb:2:in `<main>'
    28: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/frames_command.rb:3:in `<module:YARD>'
    27: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/frames_command.rb:4:in `<module:Server>'
    26: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/frames_command.rb:6:in `<module:Commands>'
    25: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
    24: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
    23: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
    22: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
    21: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
    20: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
    19: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/display_object_command.rb:2:in `<main>'
    18: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/display_object_command.rb:3:in `<module:YARD>'
    17: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/display_object_command.rb:4:in `<module:Server>'
    16: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/display_object_command.rb:6:in `<module:Commands>'
    15: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
    14: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
    13: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
    12: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
    11: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
    10: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
     9: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/library_command.rb:4:in `<main>'
     8: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/library_command.rb:5:in `<module:YARD>'
     7: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/library_command.rb:6:in `<module:Server>'
     6: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/library_command.rb:32:in `<module:Commands>'
     5: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/library_command.rb:34:in `<class:LibraryCommand>'
     4: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.1.4.1/lib/active_support/fork_tracker.rb:8:in `fork'
     3: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.1.4.1/lib/active_support/fork_tracker.rb:8:in `fork'
     2: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.1.4.1/lib/active_support/fork_tracker.rb:10:in `block in fork'
     1: from /Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/yard-0.9.26/lib/yard/server/commands/library_command.rb:34:in `block in <class:LibraryCommand>'
/Users/grahammelcher/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/sorbet-0.5.9115/lib/require_everything.rb:94:in `block in patch_kernel': ExitCalledError (ExitCalledError)

It's a bit confusing because there's a missing newline after YARD::Server::Commands, so the error is actually:

Kernel#exit was called while requiring ruby source files

Interestingly, subsequent runs of bundle exec srb init or bundle exec srb rbi hidden-definitions fail at a slightly different place than the first run and generate slightly different sorbet files. Second run fails at Yard::Tags instead of YARD::Server::Commands. bundle exec srb rbi hidden-definitions fails at Naming YARD::Templates.

I've tried some of the suggestions from https://github.com/sorbet/sorbet/issues/975 e.g. using require: false on yard but same issue.

Open to work-arounds or suggestions on how to resolve. There's a related issue where a project called exit on load and broke srb init in the same way, and the response from the sorbet team was basically "your code is calling Kernel#exit, don't do that".

Planning to file an issue with Yard and/or Sorbet but it's unclear if they'll care to fix it, and I'm still unclear on what in the yard code is calling #exit on file load.

CodePudding user response:

The simplest solution to this is to use Tapioca to generate your signatures, rather than Sorbet's built-in rbi init/RBI generator system. It's generally better and faster in my experience.

  • Related