Fix ruby-lsp startup failures: rbenv support and Bundler isolation#1094
Fix ruby-lsp startup failures: rbenv support and Bundler isolation#1094EarthmanWeb wants to merge 4 commits intooraios:mainfrom
Conversation
When rbenv is active, ruby-lsp and gem install must be invoked via "rbenv exec" to ensure the correct Ruby version and gem environment are used. Without this, the bare shim path can resolve to a different Ruby version than the one specified in .ruby-version, causing ruby-lsp to be installed into or launched from the wrong gem environment.
Three fixes for Ruby LS failing to start in projects with native deps: 1. Set BUNDLE_GEMFILE env var pointing to .ruby-lsp/Gemfile so Bundler doesn't auto-load the project's Gemfile at Ruby startup. This is the root fix — without it, bundler/setup.rb materializes ALL project gems (e.g. mysql2) before ruby-lsp starts. 2. Write a minimal .ruby-lsp/Gemfile containing only ruby-lsp gem. 3. Create bundle_is_composed marker so ruby-lsp skips its own composed bundle setup.
rbs >= 3.9 uses bare Pathname() which is only available in Ruby 3.4+. When ruby-lsp pulls in rbs 3.10.x on Ruby 3.3.6, it crashes with NoMethodError: undefined method 'Pathname' for class RBS::EnvironmentLoader.
|
🎉 |
MischaPanch
left a comment
There was a problem hiding this comment.
I can't say I understand what's going on here and the implementation is becoming even more unmaintainable, with all the branching logic and the various scenarios and returns. But if you say it improves the status quo for ruby, I'm going to trust it. Just a minor question to address
@kiakiraki FYI - if you have time, I would appreciate your input on this
| # Create a minimal .ruby-lsp bundle environment to isolate ruby-lsp | ||
| # from the project's Gemfile. Without this, Bundler auto-loads the | ||
| # project's gems at Ruby startup (via bundler/setup.rb), failing if | ||
| # any gem has unmet native dependencies (e.g. mysql2). |
There was a problem hiding this comment.
Why is it a problem if it fails? Can't we assume that all native dependencies were installed?
There was a problem hiding this comment.
When a maintainer inherits a cloned repo where the .serena/project.yml config is stored and shared with the repo, but the maintainer is not actively working on the ruby parts of the project (in my case) then the unmet ruby requirements cause the LSP servers to ALL fail, because of these unmet dep's.
In my other PR, #1095 I suggested that a single failure should not kill all serena language servers - If that was adopted then this might be a moot point, unless in fact it also causes a problem if the dep's ARE all installed locally.
In any case, dep's installed or not, seems like extra overhead for it to fire up the sequence of checking all the references are accurate, simply to allow for LSP reading/editing.
There was a problem hiding this comment.
Concerning your actual problem - we are soon (probably today or tomorrow) merging a solution for that. You will be able to add project.local.yml which is your personal config and not checked in. It can override the settings in the shared project.yml, so you can configure your own language list, excluding ruby. @ddarbyson this is exactly what you want, right?
As to this block - it makes sense to support this, but it shouldn't be the default and it should be configurable through ls_specific_options. There one could add a flag use_standalone_rbenv_bundle which by default is false. If you want to do that, feel free to extend the PR and the corresponding documentation. Otherwise, you can also just delete this blog.
As @opcode81 and I mentioned before, while silently failing to start an LS might be suitable behavior for you, for many users it's entirely unacceptable to silently not have their languages configuration respected.
There was a problem hiding this comment.
@MischaPanch
Thanks for the feedback
RE: "but it shouldn't be the default "
Why would you say that?
Isn't decreased overload (loading the entire Ruby setup) for startup a benefit?
Would it break something else, if it's used by default?
Does it require the project's full Ruby env loaded, just to use lsp on the files?
There was a problem hiding this comment.
RE: "we are soon (probably today or tomorrow) merging a solution for that. You will be able to add project.local.yml which is your personal config and not checked in. It can override the settings in the shared project.yml, so you can configure your own language list, excluding ruby."
Awesome! Great work.
There was a problem hiding this comment.
Would it break something else, if it's used by default?
I honestly don't know, that's why I'm cautious. Maybe it's fine, or maybe some LSP functionality gets lost this way. Since I can't test, I'm hesitant to make a change that will affect ruby users. If you know for sure that it's fine, we can keep it
There was a problem hiding this comment.
Also, it makes our code more complex ;)
|
Those Ruby guys eh? Don't want to hi-jack the topic. I get @EarthmanWeb scenario. It would be nice if Serena could use similar Last time I looked that wasn't available so we removed Serena from the stack. |
|
@ddarbyson support for @EarthmanWeb please let us know whether you think the additions in this PR are still relevant. As a non-Ruby user, I cannot evaluate this. |
|
Disclaimer: I'm not a maintainer of this project — just a third-party observer sharing my perspective.
|
|
@EarthmanWeb will you implement @kiakiraki's suggestions? |
|
On Vacation presently, will review after March 28
T
…On Thu, Mar 12, 2026 at 5:37 AM Dr. Dominik Jain ***@***.***> wrote:
*opcode81* left a comment (oraios/serena#1094)
<#1094 (comment)>
@EarthmanWeb <https://github.com/EarthmanWeb> will you implement
@kiakiraki <https://github.com/kiakiraki>'s suggestions?
—
Reply to this email directly, view it on GitHub
<#1094 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABMTWGPOPP5X7DLC3WP2QG34QKOOLAVCNFSM6AAAAACWA6OTJ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DANBWGA2DMNBZGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Problem
ruby-lsp fails to start in two common setups:
1. rbenv-managed Ruby
When rbenv is active, ruby-lsp is launched via the shim path (e.g.
~/.rbenv/shims/ruby-lsp). Shims route through rbenv at runtime, butthe gem environment they resolve to can differ from the Ruby version
specified in
.ruby-version. This causes ruby-lsp to run under thewrong Ruby version or fail to find gems entirely.
2. Projects with native gem dependencies (e.g. mysql2, pg)
Ruby's Bundler auto-loads the project's
Gemfileat startup viabundler/setup.rb. If any gem in the project requires native extensionsthat aren't compiled (e.g.
mysql2withoutlibmysqlclient), theRuby process fails before ruby-lsp even initialises. This affects any
project using database gems.
Fix
Three targeted changes, all in
ruby_lsp.py:1. rbenv: launch via
rbenv execWhen
use_rbenvis detected, ruby-lsp is launched as["rbenv", "exec", "ruby-lsp"]instead of via the shim path. Thisensures the correct Ruby version and gem environment are always used.
Same fix applied to
gem installwhen ruby-lsp is not yet installed.2.
BUNDLE_GEMFILEisolationSets
BUNDLE_GEMFILE=.ruby-lsp/Gemfilein the process environmentbefore launching ruby-lsp. This prevents Bundler from auto-loading
the project's
Gemfile, isolating ruby-lsp from native project gems.3. Minimal composed bundle
Pre-creates
.ruby-lsp/Gemfile(with onlyruby-lsp+rbs < 3.9for Ruby < 3.4 compatibility) and the
bundle_is_composedmarker fileso ruby-lsp skips its own bundle setup entirely. Stale
Gemfile.lockand
main_lockfile_hashfrom failed previous attempts are cleaned up.Example
Before this fix, opening a Rails project with
gem "mysql2"in itsGemfilewould produce:...and ruby-lsp would never start.
After this fix, ruby-lsp starts cleanly because Bundler never sees
the project's
Gemfile.