visit_Psych_Nodes_Alias: 不明なエイリアス: デフォルト (Psych::BadAlias)
概要
Ruby 2.7.1 から 3.1.1 に更新し、Gemfile.lock を削除してバンドル更新を実行しました (開発ブランチ上にあるので、これが悪いアイデアであれば破棄できます。機能するかどうかを確認したかっただけです) )。
バンドルの更新は成功しましたが、サーバーを起動すると次のようになります。
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>'
「psych」エラー メッセージをグーグルで検索すると、関連している可能性があることがわかります。しかし、アプリ全体で YAML.safe_load (または、safe_load だけ) を検索すると、その出現は 0 件あります。 (アプリ内で実際の gem を検索する必要があるでしょうか?)。
かなりの確率でしたが、このコメントに基づいて gem rdoc –all を実行して、すべての rdoc ドキュメントを更新しました。しかし、それは役に立ちませんでした。
解決策
この問題は、この号で説明されている Ruby 3.1 / Psych 4.x の非互換性に関連しています: https://bugs.ruby-lang.org/issues/17866
Ruby 3.0 には Psych 3 が付属していますが、Ruby 3.1 には Psych 4 が付属しており、これには大きな破壊的変更 (差分 3.3.2 → 4.0.0) があります。
現時点では、Ruby 3.1 以前と同じ方法で YAML をロードしたい人はどこにいても、次のようなことを行う必要があるようです。
begin
YAML.load(source, aliases: true, **options)
rescue ArgumentError
YAML.load(source, **options)
end
Rails チームによってパッチが適用されたもの。
あなたの場合、Ruby 3.1 にアップグレードする前に、メジャー バージョンの設定に一致する Rails バージョンにこのパッチが含まれているかを確認する必要があると思います。
個人的には、YAML をロードするコードを制御できる場合はどこでも、次のような拡張機能を追加しています。
module YAML
def self.properly_load_file(path)
YAML.load_file path, aliases: true
rescue ArgumentError
YAML.load_file path
end
end
または、Psych 4 で行われたこの変更を完全に元に戻したい場合は、これをコードに追加します。
module YAML
class << self
alias_method :load, :unsafe_load if YAML.respond_to? :unsafe_load
end
end
これには、YAML::load と YAML::load_file (それを使用する) を元の状態に復元できるという利点があり、Ruby のすべてのバージョンで、制御できないライブラリを含むすべてが解決されます。
最後に、コメントで述べたように、侵襲性を最小限に抑えた一時しのぎの手段を希望する場合は、Gemfile で Psych を < 4 に固定することで回避できる可能性があります。
gem 'psych', '< 4'
ActiveRecord 7.0.3.1 では内部呼び出しが変更され、safe_load を直接呼び出すようになりました。 Rails テスト中に Psych 関連のエラーが発生した場合は、この変更の影響を受ける可能性があります。
これを解決するには、これを新規または既存のイニシャライザに追加します。
# config/initializers/activerecord_yaml.rb
ActiveRecord.use_yaml_unsafe_load = true
代わりに ActiveRecord.yaml_column_permitted_classes を使用して、許可されたクラスを構成することもできます。
詳細については、この投稿をご覧ください。