Skip to content

Ruby 3.1: YamlSyntax crashes when checking Rails database.yml #769

@mattbrictson

Description

@mattbrictson

Ruby 3.1 comes with psych 4.0.0, which changes the behavior of YAML.load_file. Now, safe mode is used by default. This means (among other things) that aliases are not resolved. So &default used in a typical YAML file like database.yml in Rails will not be resolved and results in a parsing error.

More background on the psych 4.0.0 change here: https://bugs.ruby-lang.org/issues/17866

As a result, YamlSyntax crashes when used with Ruby 3.1 on a typical Rails code base.

Here is an example of running overcommit on a Rails project:

$ overcommit --run
Running pre-commit hooks
Check if database schema is up to date..........[RailsSchemaUpToDate] OK
Check YAML syntax........................................[YamlSyntax] FAILED
Hook raised unexpected error
Unknown alias: default
ruby/3.1.0/psych/visitors/to_ruby.rb:430:in `visit_Psych_Nodes_Alias'
ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each'
ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each_slice'
ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `revive_hash'
ruby/3.1.0/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each'
ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each_slice'
ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `revive_hash'
ruby/3.1.0/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:318:in `visit_Psych_Nodes_Document'
ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
ruby/3.1.0/psych.rb:335:in `safe_load'
ruby/3.1.0/psych.rb:370:in `load'
ruby/3.1.0/psych.rb:671:in `block in load_file'
ruby/3.1.0/psych.rb:670:in `open'
ruby/3.1.0/psych.rb:670:in `load_file'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook/pre_commit/yaml_syntax.rb:11:in `block in run'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook/pre_commit/yaml_syntax.rb:9:in `each'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook/pre_commit/yaml_syntax.rb:9:in `run'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook/base.rb:47:in `block in run_and_transform'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/utils.rb:260:in `with_environment'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook/base.rb:47:in `run_and_transform'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook_runner.rb:161:in `run_hook'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook_runner.rb:97:in `block in consume'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook_runner.rb:94:in `loop'
ruby/gems/3.1.0/gems/overcommit-0.58.0/lib/overcommit/hook_runner.rb:94:in `consume'

A possible fix is to do what Rails has already done, and pass the aliases: true option when calling YAML.load_file.

rails/rails@179d0a1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions