visit_Psych_Nodes_Alias: Unknown alias: default (Psych::BadAlias)
Asked Answered
D

6

93

I updated from ruby 2.7.1 to 3.1.1, then removed Gemfile.lock and ran bundle update (it's on a dev branch, so I can throw it away if this is a bad idea, I just wanted to see if it would work).

bundle update succeeds, but when I start the server:

rails s
=> Booting Puma
=> Rails 7.0.2.2 application starting in development 
=> Run `bin/rails server --help` for more startup options
Exiting
/Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:430:in `visit_Psych_Nodes_Alias': Unknown alias: default (Psych::BadAlias)
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each_slice'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `revive_hash'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `each_slice'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:343:in `revive_hash'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:318:in `visit_Psych_Nodes_Document'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych.rb:335:in `safe_load'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/psych.rb:370:in `load'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/env.rb:30:in `available_environments'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/env.rb:21:in `current'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/env.rb:15:in `inquire'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/env.rb:7:in `inquire'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/instance.rb:11:in `env'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/instance.rb:18:in `config'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker.rb:34:in `config'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/webpacker-4.3.0/lib/webpacker/railtie.rb:32:in `block in <class:Engine>'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/initializable.rb:32:in `instance_exec'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/initializable.rb:32:in `run'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/initializable.rb:61:in `block in run_initializers'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:228:in `block in tsort_each'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:431:in `each_strongly_connected_component_from'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:349:in `block in each_strongly_connected_component'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:347:in `each'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:347:in `call'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:347:in `each_strongly_connected_component'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:226:in `tsort_each'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/3.1.0/tsort.rb:205:in `tsort_each'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/initializable.rb:60:in `run_initializers'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/application.rb:372:in `initialize!'
    from /Users/st/rails/hangswith/config/environment.rb:5:in `<main>'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bootsnap-1.10.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bootsnap-1.10.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/zeitwerk-2.5.4/lib/zeitwerk/kernel.rb:35:in `require'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bootsnap-1.10.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:42:in `require_relative'
    from config.ru:3:in `block in <main>'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `eval'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `new_from_string'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:105:in `load_file'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:66:in `parse_file'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/server.rb:349:in `build_app_and_options_from_config'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/server.rb:249:in `app'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/rack-2.2.3/lib/rack/server.rb:422:in `wrapped_app'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/commands/server/server_command.rb:76:in `log_to_stdout'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/commands/server/server_command.rb:36:in `start'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/commands/server/server_command.rb:143:in `block in perform'
    from <internal:kernel>:90:in `tap'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/commands/server/server_command.rb:134:in `perform'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/command/base.rb:87:in `perform'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/command.rb:48:in `invoke'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/railties-7.0.2.2/lib/rails/commands.rb:18:in `<main>'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bootsnap-1.10.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
    from /Users/st/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bootsnap-1.10.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
    from bin/rails:4:in `<main>'

What I've tried

Googling the 'psych' error message reveals this which may be related. But when I search the entire app for YAML.safe_load (or even just safe_load), there are 0 occurrences of it. (perhaps I should be searching actual gems in my app?).

It was a long shot but based on this comment, I ran gem rdoc --all to update all rdoc documentation. But that didn't help.

Dharna answered 20/2, 2022 at 5:50 Comment(0)
J
156

The problem is related to the Ruby 3.1 / Psych 4.x incompatibility described in this issue: https://bugs.ruby-lang.org/issues/17866

Ruby 3.0 comes with Psych 3, while Ruby 3.1 comes with Psych 4, which has a major breaking change (diff 3.3.2 → 4.0.0).

  • The new YAML loading methods (Psych 4) do not load aliases unless they get the aliases: true argument.
  • The old YAML loading methods (Psych 3) do not support the aliases keyword.

At this point, it seems like anyone, anywhere that wants to load YAML in the same way it worked prior to Ruby 3.1, need to do something like this:

begin
  YAML.load(source, aliases: true, **options)
rescue ArgumentError
  YAML.load(source, **options)
end

as patched by the Rails team.

In your case, I suspect you will need to see which Rails version that matches your major version preference includes this patch before you can upgrade to Ruby 3.1.

Personally, wherever I have control of the code that loads YAML, I am adding an extension like this:

module YAML
  def self.properly_load_file(path)
    YAML.load_file path, aliases: true
  rescue ArgumentError
    YAML.load_file path
  end
end

or, if I want to completely revert this change done in Psych 4, I add this to my code:

module YAML
  class << self
    alias_method :load, :unsafe_load if YAML.respond_to? :unsafe_load
  end
end

This has the advantage of restoring YAML::load, and YAML::load_file (which uses it) to their original glory, and solves everything including libraries that you have no control of, in all Ruby versions.

Lastly, as I mentioned in the comments, in case you prefer a minimally invasive stopgap measure, you might be able to get away with pinning Psych to < 4 in your Gemfile:

gem 'psych', '< 4'

Note for Rails users (>= 7.0.3.1)

ActiveRecord 7.0.3.1 changed an internal call and it now calls safe_load directly. If you see a Psych related error during rails tests, you might be affected by this change.

To resolve it, you can add this to a new or existing initializer:

# config/initializers/activerecord_yaml.rb
ActiveRecord.use_yaml_unsafe_load = true

You may also use ActiveRecord.yaml_column_permitted_classes to configure the allowed classes instead.

More info in this post.

Jabon answered 20/2, 2022 at 9:21 Comment(7)
Thank you for the great explanation! Unfortunately I'm on rails 7.0.2.2, which is most recent version, at least according to rubygems. I wonder if there's a way to get an even more up to date version?Dharna
Since that patch was in May last year, I'm starting to wonder if perhaps a particular gem I'm using this the incompatibility somehow? Afterthought: hmm.. unlikely since all the gems are up to date (since I ran bundle update)Dharna
Then yes, the problem is probably with some other gem, perhaps webpacker according to your error log. This is a major headache breaking change, I believe it will take some time for all gems to work around it. In my opinion, the Psych team did not properly appreciate the ripple effects when introducing this change.Jabon
I hate to give up so easily, but in the interest of finding a practical solution, I think it's best for me to revert to ruby 3.0.3, so as to use the latest ruby version that doesn't use psych 4. Do you think that's a good idea? (at least for now, until everything has caught up)Dharna
Absolutely yes in regards to reverting to Ruby < 3.1. From my experience, it takes time until the gem developers community will update their gems, and quite frankly - there is not much that can be done now other than downgrading, and reporting issues in offending gems.Jabon
One last note: If Ruby 3.1 is desired, you might be able to pin gem 'psych', '< 4' in your Gemfile, unless some other gem requires >= 4, it might work.Jabon
Just wanted to report back that after dropping back to ruby 3.0.3, everything worked immediately and painlessly.Dharna
C
25

I ran into the same problem, using a very recent version of rails and ruby 3.1.1 and the suggestion that DannyB mentioned fixed my problem.

In my Gemfile, I put webpacker3 and specified psych < 4. I don't know yet if this version of psych will break something down the road but at least webpacker installed:

gem 'webpacker', '~>3.0'

gem 'psych', '< 4'

Cheka answered 16/3, 2022 at 19:34 Comment(2)
Thanks this worked. Personally, I think this should be the accepted solution because it's not our job as Rails devs to fix ruby bugs. I prefer this to any workaround, at least until Psych 4+ is patched.Elysia
From what I see, it is unlikely that Psych 4 will revert back to the original behavior.Jabon
S
13

In my case I had ruby version 3.0.3 on gem 'rails', '~> 6.1.5' My default system version was locked to psych (default: 3.3.2) but somehow Gemfile.lock had stuff broken with:

psych (4.0.3)
  stringio

sdoc (2.3.1)
rdoc (>= 5.0, < 6.4.0)

The solution was to remove those, then lock correct version of Psych in Gemfile

gem 'psych', '< 4

Then bundle install which fixed the circular broken dependencies

Serapis answered 26/4, 2022 at 22:59 Comment(0)
D
7

A simple solution: downgrade to ruby 3.0.X

This is simple and easy, requires no code changes, and can be upgraded to ruby 3.1.x in the near future when everything's caught up and is compatible with Psych 4.

Note: ruby 3.0.3 is the latest ruby version which still uses Psych 3.x.x, so there are no problems and everything just works.

Why this solution?

I prefer this option because patching an app or its gems can get complicated and I prefer the simplest/safest solution.

See here and here for the advice that helped me make the decision:

I think it's best to revert to ruby 3.0.3, so as to use the latest ruby version that doesn't use psych 4. Do you think that's a good idea?

Absolutely yes in regards to reverting to Ruby < 3.1 ... it takes time until the gem developers community will update their gems

Why not downgrade psych instead?

The only reason I didn't downgrade psych gem instead of ruby is because I'm not 100% sure that doing so won't cause problems elsewhere, potentially things that are hard to detect. Although it could be a completely viable solution (I'm just not sure that it is, hence I prefer to play it safe and downgrade ruby instead).

Dharna answered 19/3, 2022 at 1:40 Comment(6)
Well, this is a stopgap measure. Eventually, you will need to upgrade.Jabon
@Jabon for sure 👍 As you explained in your answer above, gems will catch up eventually. I'll give it 6 months and try again :) (I wrote this answer just to make sure people realised there is an easy workaround if they're willing to roll ruby 3.0.3 for a while)Dharna
Latest Ruby 3.0 is now 3.0.4, I'm guessing your headline is best read as: "downgrade to ruby 3.0.X"Thier
@Thier great idea, doneDharna
Nov. 2022. Got the error, so not fixed yet. Was using Ruby 3.1.2, but downgraded to get rid of the errors. I couldn't compile ruby 3.0.3 or 3.0.4, so am running 3.0.2Lohner
Works now on Ruby 3.1.2 and Rails 6.1.7. Was doing upgrades and got same errors as above. Locked psych gem to 3.3.4 (wanted Ruby 3.1.2 to use Heroku stack-22). Upgraded to ruby from 2.6.6 to 3.1.2 then rails from 6.0.6 to 6.1.7. Then removed psych lock and it works now.Thermoscope
C
2

in my case, after update to ruby 3.1.2 updating to rails 7.0.4 solved it.

Coca answered 4/1, 2023 at 15:0 Comment(0)
U
0

I am upgrading an app to rails 7.1.3 and ran into the same issue. I was able to resolve by changing in my initializers

YAML.load(file_name)[Rails.env].symbolize_keys

to

YAML.load(file_name, aliases: true)[Rails.env].symbolize_keys
Udele answered 8/5 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.