ruby-i18n / i18n

Internationalization (i18n) library for Ruby
MIT License
977 stars 408 forks source link

can't modify frozen Hash: {} (FrozenError) #613

Closed lavrovdv closed 2 years ago

lavrovdv commented 2 years ago

Default parameter options = EMPTY_HASH in method def resolve(locale, object, subject, options = EMPTY_HASH) is a frozen Hash, options.delete(:fallback_in_progress) raise can't modify frozen Hash: {} (FrozenError) https://github.com/ruby-i18n/i18n/blob/a1dc4244fc73418a3c0860592b1884da94017992/lib/i18n/backend/fallbacks.rb#L72

radar commented 2 years ago

@lavrovdv Thank you for filing this issue. How can I replicate this issue on a new application myself? Could you please provide exact steps to reproduce.

lavrovdv commented 2 years ago

I got this error in rails app in production env.

Loading production environment (Rails 6.1.4.4)
irb(main):001:0> I18n.t!(:"date.month_names", :locale => :ru, :format => "%B %Y")
.../bundle/ruby/3.0.0/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:72:in `delete': can't modify frozen Hash: {} (FrozenError)
radar commented 2 years ago

I'm currently unable to reproduce this issue in any Rails application of mine. Could you please create a Rails app repo on GitHub and share it here?

yaroslav commented 2 years ago

I am having the exact same error with the same locale; persists in production, but can't reproduce in the local environment so far.

It started after the update to Rails 6.0.4.6 which updated i18n to 1.9.1.

Mine dies on things as simple as l(from, format: '%d %B %Y').

    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:72 :in `delete`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:72 :in `block in resolve`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:71 :in `catch`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:71 :in `resolve`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:147 :in `block in resolve`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:141 :in `catch`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:141 :in `resolve`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:69 :in `resolve`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:35 :in `translate`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:50 :in `block (2 levels) in translate`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:49 :in `catch`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:49 :in `block in translate`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:47 :in `each`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/fallbacks.rb:47 :in `translate`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n.rb:221 :in `block in translate`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n.rb:217 :in `catch`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n.rb:217 :in `translate`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n.rb:236 :in `translate!`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:277 :in `block in translate_localization_format`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:269 :in `gsub`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:269 :in `translate_localization_format`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n/backend/base.rb:85 :in `localize`
    [GEM_ROOT]/gems/i18n-1.9.1/lib/i18n.rb:316 :in `localize`
yaroslav commented 2 years ago

Freezing i18n to ~1.8 solved the issue for me.

Now, both me and Dmitry @lavrovdv seem to have the same locale, :ru. That means that either Dmitry uses my russian gem that has not been touched in years, and I mean years unfortunately (although IIRC the API did not change much), or they use a .yml+.rb extract from it that has been shared around as Russian localization for Rails. My app uses the gem.

Unfortunately, I have not been able to pinpoint the issue to the gem exactly: everything works in my local environment, but dies in production. The gem does not hack or overload I18n in anyway, just wraps around it. Here are the localization files supplied: https://github.com/yaroslav/russian/tree/master/lib/russian/locale.

You can see that the datetime (as well as plulralization) is actually a lambda: https://github.com/yaroslav/russian/blob/master/lib/russian/locale/datetime.rb, which is important for Cyrillic languages and was working more or less as intended for almost 11 years now.

Somestuffman commented 2 years ago

Also having the same issue with date localization after updating to 1.9.1. Seems https://github.com/ruby-i18n/i18n/pull/622 fixes the problem.

radar commented 2 years ago

I18n 1.10.0 has just been released, and I think it'll fix this problem.