Search code examples
ruby-on-railsactionmailersidekiqrails-activejobruby-on-rails-6

Rails 6 ActiveJob undefined constant ActionMailer::MailDeliveryJob


I'm upgrading an app to Rails 6 and after fixing all breaking changes I'm now facing an error when sending emails from background jobs.

I use Sidekiq through ActiveJob and I believe I've added the necessary config changes:

# config/application.rb

...

config.load_defaults 6.0

# config/initializers/new_framework_defaults_6_0.rb

...

Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"

I'm sending emails using deliver_later, like: UserMailer.notify(user).deliver_later

One important aspect is that the emails ARE being delivered even though I'm getting the error

Error message:

NameError:
uninitialized constant ActionMailer::MailDeliveryJob
Did you mean?  ActionMailer::DeliveryJob

According to Rollbar the context of the error is ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper

Any help is appreciated, thanks!


Solution

  • ActionMailer::MailDeliveryJob is new for rails 6, previously it was called ActionMailer::DeliveryJob (and is still present in rails 6 but with deprecation warning for smoother migration)

    Looks like you have a situation when jobs from new rails ended up in a sidekiq worker that is still running previous version. Since emails are actually being delivered - most probably you have workers with both rails versions at the same time. Some workers generate the error and job is retried until it is picked by a worker that finally delivers.

    To prevent the error it's better to deploy with action_mailer.delivery_job = "ActionMailer::DeliveryJob", make sure all workers are upgraded (=restarted with new code) and only then remove deprecation warning by switching to MailDeliveryJob.