Visit_Psych_Nodes_Alias: Unknown Alias: Default (Psych::Badalias)

visit_Psych_Nodes_Alias: Unknown alias: default (Psych::BadAlias)

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.

rails4 - Psych::BadAlias: Unknown alias: test

I don't believe you can alias test, development, or production as they are assigned based on the environment you boot in (if environment is production, the production settings will be applied). The issue is that if this were to work, cucumber would only be usable in the test environment.

I used something akin to the below:

  base: &base
adapter: mysql2
host: address.com
encoding: utf8
adapter: mysql2
username: xxxxxx
password: xxxxxx

development:
database: db_dev
<<: *base

test:
database: db_test
<<: *base

production:
database: db_prod
<<: *base

cucumber:
database: cucumber
<<: *base

Psych::BadAlias: Unknown alias: 1 when running rake jobs:work

I got the same issue after ruby upgrade from 2.1.5 to 2.3.8. Thats latest ruby version that could be run with rails 4.1.8.

Upgrading to the latest version of delayed_job did not help. Also tried to specify downgraded version of psych gem in my Gemfile. This did work not as well.

The real issue is that if error appears on job parsing stage then delayed_job does not update last_error column.

So I just went though all the jobs and checked if it could be parsed or not:

failing_jobs = []

Delayed::Job.find_each do |job|
begin
# this code is from dj source https://github.com/collectiveidea/delayed_job/blob/master/lib/delayed/psych_ext.rb#L15
yaml = job.handler
result = Psych.parse(yaml)
result ? Delayed::PsychExt::ToRuby.create.accept(result) : result
rescue Psych::BadAlias => e
failing_jobs << job
end
end

In my case it were 6 jobs out of ~3k that could be deleted safely so I got lucky :)

Refs:

https://github.com/collectiveidea/delayed_job/pull/867

https://github.com/collectiveidea/delayed_job_mongoid/pull/65

Unknown alias when loading any yaml file

If you use safe_load you need to explicitly enable aliases:

YAML.safe_load path_to_yaml, [], [], true


Related Topics



Leave a reply



Submit