Reproduction
source = %q!a( id: nil }!
require "ripper"
require "prism"
require "prism/translation/ripper"
puts RUBY_DESCRIPTION
puts "Prism #{Prism::VERSION}"
p Ripper.lex(source)
p Prism::Translation::Ripper.lex(source)
p Prism.lex_compat(source).value
Expected
MRI 4.0.5 native Ripper.lex emits the unmatched closing brace as:
[[1, 11], :on_embexpr_end, "}", END]
Actual
Prism::Translation::Ripper.lex emits it as:
[[1, 11], :on_rbrace, "}", END]
Prism.lex_compat(source).value also emits :on_rbrace.
Environment
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [arm64-darwin22] Prism 1.9.0
I also checked Prism 1.8.1, which showed the same :on_rbrace behavior.
Notes
The input is invalid Ruby, and both MRI and Prism raise with syntax errors enabled:
Ripper.lex(source, raise_errors: true)
# SyntaxError: syntax error, unexpected '}', expecting ')'
Prism::Translation::Ripper.lex(source, raise_errors: true)
# SyntaxError: unexpected '}'; expected a `)` to close the arguments
So this may be an invalid-input compatibility gap rather than a parser correctness bug.
I originally reported this against TruffleRuby because TruffleRuby 34.0.1’s ::Ripper.lex returns :on_rbrace here. @eregon pointed out that TruffleRuby uses Prism::Translation::Ripper for ::Ripper, so this appears to belong upstream in Prism.
This was found while removing obsolete TruffleRuby/Ripper guards from Haml after TruffleRuby added Ripper support: haml/haml#1210
Reproduction
Expected
MRI 4.0.5 native Ripper.lex emits the unmatched closing brace as:
[[1, 11], :on_embexpr_end, "}", END]Actual
Prism::Translation::Ripper.lex emits it as:
[[1, 11], :on_rbrace, "}", END]Prism.lex_compat(source).value also emits
:on_rbrace.Environment
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [arm64-darwin22] Prism 1.9.0
I also checked Prism 1.8.1, which showed the same
:on_rbracebehavior.Notes
The input is invalid Ruby, and both MRI and Prism raise with syntax errors enabled:
So this may be an invalid-input compatibility gap rather than a parser correctness bug.
I originally reported this against TruffleRuby because TruffleRuby 34.0.1’s ::Ripper.lex returns :on_rbrace here. @eregon pointed out that TruffleRuby uses Prism::Translation::Ripper for ::Ripper, so this appears to belong upstream in Prism.
This was found while removing obsolete TruffleRuby/Ripper guards from Haml after TruffleRuby added Ripper support: haml/haml#1210