-
Notifications
You must be signed in to change notification settings - Fork 212
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Ruby LSP Information
Ruby LSP Version: 0.25.0
Ruby Version: 3.4.3
RuboCop Version: 1.78.0
Operating System: macOS Darwin 24.5.0
Editor: Neovim 0.11.2 with AstroNvim
LSP Client: Built-in Neovim LSP
Reproduction steps
- Start the Ruby LSP in Neovim with ruby-lsp configured to use RuboCop formatter
- Open a Ruby file that ends with a newline character (e.g., a file that is 318 bytes with the last character being a newline)
- Trigger formatting (e.g., save the file with format-on-save enabled)
- Ruby LSP crashes with an IndexError from RuboCop
Code snippet or error message
File being formatted (/Users/ianks/src/github.com/Shopify/liquid-vm/bench/benchmarks/filters/append.rb
):
# frozen_string_literal: true
require_relative "../../bench_helper"
require "yaml"
environment = { "var0" => "hello", "var1" => "world" }
template =
"{{ var0 | append: var1 }}{{ var0 | append: 'world' }}{{ 'hello' | append: var1 }}{{ 'hello' | append: 'world' }}"
bench("filter_append", environment:, template:)
00000000 23 20 66 72 6f 7a 65 6e 5f 73 74 72 69 6e 67 5f |# frozen_string_|
00000010 6c 69 74 65 72 61 6c 3a 20 74 72 75 65 0a 0a 72 |literal: true..r|
00000020 65 71 75 69 72 65 5f 72 65 6c 61 74 69 76 65 20 |equire_relative |
00000030 22 2e 2e 2f 2e 2e 2f 62 65 6e 63 68 5f 68 65 6c |"../../bench_hel|
00000040 70 65 72 22 0a 72 65 71 75 69 72 65 20 22 79 61 |per".require "ya|
00000050 6d 6c 22 0a 0a 20 65 6e 76 69 72 6f 6e 6d 65 6e |ml".. environmen|
00000060 74 20 3d 20 7b 20 22 76 61 72 30 22 20 3d 3e 20 |t = { "var0" => |
00000070 22 68 65 6c 6c 6f 22 2c 20 22 76 61 72 31 22 20 |"hello", "var1" |
00000080 3d 3e 20 22 77 6f 72 6c 64 22 20 7d 0a 74 65 6d |=> "world" }.tem|
00000090 70 6c 61 74 65 20 3d 0a 20 20 22 7b 7b 20 76 61 |plate =. "{{ va|
000000a0 72 30 20 7c 20 61 70 70 65 6e 64 3a 20 76 61 72 |r0 | append: var|
000000b0 31 20 7d 7d 7b 7b 20 76 61 72 30 20 7c 20 61 70 |1 }}{{ var0 | ap|
000000c0 70 65 6e 64 3a 20 27 77 6f 72 6c 64 27 20 7d 7d |pend: 'world' }}|
000000d0 7b 7b 20 27 68 65 6c 6c 6f 27 20 7c 20 61 70 70 |{{ 'hello' | app|
000000e0 65 6e 64 3a 20 76 61 72 31 20 7d 7d 7b 7b 20 27 |end: var1 }}{{ '|
000000f0 68 65 6c 6c 6f 27 20 7c 20 61 70 70 65 6e 64 3a |hello' | append:|
00000100 20 27 77 6f 72 6c 64 27 20 7d 7d 22 0a 0a 62 65 | 'world' }}"..be|
00000110 6e 63 68 28 22 66 69 6c 74 65 72 5f 61 70 70 65 |nch("filter_appe|
00000120 6e 64 22 2c 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 |nd", environment|
00000130 3a 2c 20 74 65 6d 70 6c 61 74 65 3a 29 0a |:, template:).|
0000013e
Error message:
Formatting failed with
: /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/lsp/stdin_runner.rb:67:in 'RuboCop::Lsp::StdinRunner#run': An internal error occurred for the Layout/EmptyLinesAroundArguments cop. (RubyLsp::Requests::Support::InternalRuboCopError)
Updating to a newer version of RuboCop may solve this.
For more details, run RuboCop on the command line.
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/lsp/runtime.rb:43:in 'RuboCop::LSP::Runtime#format'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/ruby_lsp/rubocop/runtime_adapter.rb:28:in 'RubyLsp::RuboCop::RuntimeAdapter#run_formatting'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/requests/formatting.rb:35:in 'RubyLsp::Requests::Formatting#perform'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/server.rb:657:in 'RubyLsp::Server#text_document_formatting'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/server.rb:46:in 'RubyLsp::Server#process_message'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/base_server.rb:162:in 'block in RubyLsp::BaseServer#new_worker'
/Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:176:in 'RuboCop::Cop::Commissioner#with_cop_error_handling': cause: #<IndexError: The range 317...318 is outside the bounds of the source> (RuboCop::ErrorWithAnalyzedFileLocation)
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:106:in 'block in RuboCop::Cop::Commissioner#trigger_responding_cops'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:105:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:105:in 'RuboCop::Cop::Commissioner#trigger_responding_cops'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:69:in 'RuboCop::Cop::Commissioner#on_send'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:146:in 'block in RuboCop::AST::Traversal#on_dstr'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:146:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:146:in 'RuboCop::AST::Traversal#on_dstr'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:71:in 'RuboCop::Cop::Commissioner#on_begin'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:20:in 'RuboCop::AST::Traversal#walk'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:87:in 'RuboCop::Cop::Commissioner#investigate'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/team.rb:174:in 'RuboCop::Cop::Team#investigate_partial'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/team.rb:101:in 'RuboCop::Cop::Team#investigate'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:348:in 'block in RuboCop::Runner#inspect_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:347:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:347:in 'Enumerable#flat_map'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:347:in 'RuboCop::Runner#inspect_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:290:in 'block in RuboCop::Runner#do_inspection_loop'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:324:in 'block in RuboCop::Runner#iterate_until_no_changes'
from <internal:kernel>:168:in 'Kernel#loop'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:317:in 'RuboCop::Runner#iterate_until_no_changes'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:286:in 'RuboCop::Runner#do_inspection_loop'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:167:in 'block in RuboCop::Runner#file_offenses'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:192:in 'RuboCop::Runner#file_offense_cache'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:166:in 'RuboCop::Runner#file_offenses'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:154:in 'RuboCop::Runner#process_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:135:in 'block in RuboCop::Runner#each_inspected_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:134:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:134:in 'Enumerable#reduce'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:134:in 'RuboCop::Runner#each_inspected_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:120:in 'RuboCop::Runner#inspect_files'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:73:in 'RuboCop::Runner#run'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/lsp/stdin_runner.rb:54:in 'RuboCop::Lsp::StdinRunner#run'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/lsp/runtime.rb:43:in 'RuboCop::LSP::Runtime#format'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/ruby_lsp/rubocop/runtime_adapter.rb:28:in 'RubyLsp::RuboCop::RuntimeAdapter#run_formatting'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/requests/formatting.rb:35:in 'RubyLsp::Requests::Formatting#perform'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/server.rb:657:in 'RubyLsp::Server#text_document_formatting'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/server.rb:46:in 'RubyLsp::Server#process_message'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/base_server.rb:162:in 'block in RubyLsp::BaseServer#new_worker'
/Users/ianks/.gem/ruby/3.4.3/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb:406:in 'Parser::Source::TreeRewriter#check_range_validity': The range 317...318 is outside the bounds of the source (IndexError)
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/corrector.rb:120:in 'RuboCop::Cop::Corrector#check_range_validity'
from /Users/ianks/.gem/ruby/3.4.3/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb:398:in 'Parser::Source::TreeRewriter#combine'
from /Users/ianks/.gem/ruby/3.4.3/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb:194:in 'Parser::Source::TreeRewriter#replace'
from /Users/ianks/.gem/ruby/3.4.3/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb:218:in 'Parser::Source::TreeRewriter#remove'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/layout/empty_lines_around_arguments.rb:53:in 'block (2 levels) in RuboCop::Cop::Layout::EmptyLinesAroundArguments#on_send'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/base.rb:426:in 'RuboCop::Cop::Base#correct'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/base.rb:210:in 'RuboCop::Cop::Base#add_offense'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/layout/empty_lines_around_arguments.rb:52:in 'block in RuboCop::Cop::Layout::EmptyLinesAroundArguments#on_send'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/layout/empty_lines_around_arguments.rb:74:in 'block in RuboCop::Cop::Layout::EmptyLinesAroundArguments#extra_lines'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/layout/empty_lines_around_arguments.rb:72:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/layout/empty_lines_around_arguments.rb:72:in 'RuboCop::Cop::Layout::EmptyLinesAroundArguments#extra_lines'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/layout/empty_lines_around_arguments.rb:51:in 'RuboCop::Cop::Layout::EmptyLinesAroundArguments#on_send'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:107:in 'Kernel#public_send'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:107:in 'block (2 levels) in RuboCop::Cop::Commissioner#trigger_responding_cops'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:171:in 'RuboCop::Cop::Commissioner#with_cop_error_handling'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:106:in 'block in RuboCop::Cop::Commissioner#trigger_responding_cops'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:105:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:105:in 'RuboCop::Cop::Commissioner#trigger_responding_cops'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:69:in 'RuboCop::Cop::Commissioner#on_send'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:146:in 'block in RuboCop::AST::Traversal#on_dstr'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:146:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:146:in 'RuboCop::AST::Traversal#on_dstr'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:71:in 'RuboCop::Cop::Commissioner#on_begin'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-ast-1.45.1/lib/rubocop/ast/traversal.rb:20:in 'RuboCop::AST::Traversal#walk'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/commissioner.rb:87:in 'RuboCop::Cop::Commissioner#investigate'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/team.rb:174:in 'RuboCop::Cop::Team#investigate_partial'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/cop/team.rb:101:in 'RuboCop::Cop::Team#investigate'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:348:in 'block in RuboCop::Runner#inspect_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:347:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:347:in 'Enumerable#flat_map'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:347:in 'RuboCop::Runner#inspect_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:290:in 'block in RuboCop::Runner#do_inspection_loop'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:324:in 'block in RuboCop::Runner#iterate_until_no_changes'
from <internal:kernel>:168:in 'Kernel#loop'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:317:in 'RuboCop::Runner#iterate_until_no_changes'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:286:in 'RuboCop::Runner#do_inspection_loop'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:167:in 'block in RuboCop::Runner#file_offenses'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:192:in 'RuboCop::Runner#file_offense_cache'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:166:in 'RuboCop::Runner#file_offenses'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:154:in 'RuboCop::Runner#process_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:135:in 'block in RuboCop::Runner#each_inspected_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:134:in 'Array#each'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:134:in 'Enumerable#reduce'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:134:in 'RuboCop::Runner#each_inspected_file'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:120:in 'RuboCop::Runner#inspect_files'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/runner.rb:73:in 'RuboCop::Runner#run'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/lsp/stdin_runner.rb:54:in 'RuboCop::Lsp::StdinRunner#run'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/rubocop/lsp/runtime.rb:43:in 'RuboCop::LSP::Runtime#format'
from /Users/ianks/.gem/ruby/3.4.3/gems/rubocop-1.78.0/lib/ruby_lsp/rubocop/runtime_adapter.rb:28:in 'RubyLsp::RuboCop::RuntimeAdapter#run_formatting'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/requests/formatting.rb:35:in 'RubyLsp::Requests::Formatting#perform'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/server.rb:657:in 'RubyLsp::Server#text_document_formatting'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/server.rb:46:in 'RubyLsp::Server#process_message'
from /Users/ianks/.gem/ruby/3.4.3/gems/ruby-lsp-0.25.0/lib/ruby_lsp/base_server.rb:162:in 'block in RubyLsp::BaseServer#new_worker'
Additional Context
- The file is exactly 318 bytes with US-ASCII encoding
- The error occurs when RuboCop's
Layout/EmptyLinesAroundArguments
cop tries to access range 317...318 - Running
rubocop --lsp
directly on the file works without issues - The issue appears to be related to how ruby-lsp calculates or passes text positions to RuboCop
- This might be related to UTF-8 vs UTF-16 position encoding differences or how line endings are counted
Workaround
Setting formatter: "none"
or using an alternative formatter like syntax_tree
avoids the crash, but this disables RuboCop formatting which many projects rely on.
activeperception, jurruh and hao-at-programa
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working