A bug was reported in Discourse where filtering on chatbot.prompt in Admin → Customize → Text fails due to a NoMethodError when the translation key is a Hash instead of a string. merefield identified that the issue arises when a translation override exists for a key that was previously a string but later changed to a Hash, causing the I18nInterpolationKeysFinder to fail. gerhard confirmed this is a regression, as Discourse should not load overrides for keys that no longer exist as strings. A workaround was provided: deleting the translation override and reloading the locale. JammyDodger noted that the fix has been implemented in a PR, resolving the issue.
NoMethodError (undefined method `scan' for {:basic=>"You are a helpful assistant.", :agent=>"You are a helpful assistant. You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with. The current date and time is %{current_date_time}. Only respond to the last question, using the prior information as context, if appropriate."}:Hash)
lib/i18n/i18n_interpolation_keys_finder.rb:6:in `find'
app/controllers/admin/site_texts_controller.rb:183:in `record_for'
app/controllers/admin/site_texts_controller.rb:249:in `block in find_translations'
app/controllers/admin/site_texts_controller.rb:234:in `each'
app/controllers/admin/site_texts_controller.rb:234:in `find_translations'
app/controllers/admin/site_texts_controller.rb:34:in `index'
app/controllers/application_controller.rb:422:in `block in with_resolved_locale'
app/controllers/application_controller.rb:422:in `with_resolved_locale'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:389:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/request_tracker.rb:233:in `call'
looks like the method in question is expecting text:
but somehow receiving a Hash:
irb(main):001:0> item = {:basic=>"You are a helpful assistant.", :agent=>"You are a helpful assistant. You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with. The current date and time is %{current_date_time}. Only respond to the last question, using the prior information as context, if appropriate."}
=>
{:basic=>"You are a helpful assistant.",
...
irb(main):002:0> item
=>
{:basic=>"You are a helpful assistant.",
:agent=>
"You are a helpful assistant. You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with. The current date and time is %{current_date_time}. Only respond to the last question, using the prior information as context, if appropriate."}
irb(main):003:0> item.scan
(irb):3:in `<main>': undefined method `scan' for {:basic=>"You are a helpful assistant.", :agent=>"You are a helpful assistant. You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with. The current date and time is %{current_date_time}. Only respond to the last question, using the prior information as context, if appropriate."}:Hash (NoMethodError)
from /home/robert/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/irb-1.6.2/exe/irb:11:in `<top (required)>'
from /home/robert/.rbenv/versions/3.2.1/bin/irb:25:in `load'
from /home/robert/.rbenv/versions/3.2.1/bin/irb:25:in `<main>'
irb(main):004:0>
Causing it to fall over … I will continue investigation
It’s being called from here, I believe:
I can repro the issue with:
I18nInterpolationKeysFinder.find(I18n.overrides_disabled { I18n.t("chatbot.prompt.system.", locale: :en) })
from the rails console.
I think this line is supposed to prevent the method receiving a Hash, but it’s not working, why?:
Moving this to Contribute > Bug, because I think this behaviour is incorrect and for some reason unreliable.
According to the code, if the value is a Hash, it should not be sent to the record_for method (where it would cause an exception as that is expecting text), but in some instances, it is.
This happens when there’s a translation override for a key that previously was a translatable string, but was converted into a Hash at a later time. That’s exactly what happened with chatbot.prompt.system.
This seems like a regression. I’m pretty sure this used to work in the past.
I can easily reproduce this with a locale file like this:
en:
foo: "this is foo"
Go to Customize → Text and override “foo” with a different value.