Why is YAML.safe_load failing on a YAML alias?
Asked Answered
S

1

19

I've a locale file in my Rails application that works fine with Rails, but when I tried to use it with react_on_rails rake task (rake react_on_rails:locale) I'm getting this error:

Psych::BadAlias: Unknown alias: item_attributes

I found that the rake task is basically calling YAML.safe_load, so I prepared the simplest example without Rails and the error is still there. Here's the sample Ruby script:

require 'yaml'

YAML.safe_load(File.open('test.yml'))

And here's the test.yml file (shorter version of the actual locale file):

pl:
  language: Polski
  dictionary_name: simple
  activerecord:
    attributes:
      line_item: &item_attributes
        variant: Produkt
        quantity: Ilosc
        price: Cena Netto
        total_price: Wartosc Netto
        vat_rate: VAT
        total_vat_amount: Kwota VAT
        total_gross_price: Wartosc Brutto
      order_item:
        <<: *item_attributes

I'm still getting the error:

/usr/local/Cellar/ruby/2.3.1/lib/ruby/2.3.0/psych/visitors/to_ruby.rb:402:in `visit_Psych_Nodes_Alias': Unknown alias: item_attributes (Psych::BadAlias)

Any ideas why this works fine with Rails but fails here? Any other way to avoid duplication in the YAML file and make it work for both Rails and YAML.safe_load?

Swash answered 24/3, 2017 at 13:19 Comment(3)
I would guess that << is not supported with YAML.safe_load. you could try if <<: {foo: bar} works. If not, this is not an alias problem.Revell
@Revell yes, it does work, so that's not itSwash
Strange indeed. There's no YAML syntax error here, maybe there are two different YAML parsers involved?Revell
T
28

I found an answer in the Psych documentation, at https://ruby-doc.org/stdlib-2.1.0/libdoc/psych/rdoc/Psych.html.

Aliases can be explicitly allowed by changing the aliases parameter. For example:

x = []
x << x
yaml = Psych.dump x
Psych.safe_load yaml               # => raises an exception
Psych.safe_load yaml, [], [], true # => loads the aliases

Whether to allow aliases or not is a boolean passed to safe_load as the fourth argument.

Tonina answered 3/5, 2017 at 18:34 Comment(1)
in 2.6 and later versions, you can use Psych.safe_load yaml, aliases: true # => loads the aliases ruby-doc.org/stdlib-2.6.3/libdoc/psych/rdoc/Psych.htmlKosaka

© 2022 - 2024 — McMap. All rights reserved.