Web Development / 03 February 2024 / by Guillermo Díaz

Devise ArgumentError while trying to reset a user's password

The Issue

In our Rails application, I encountered an ArgumentError in the Devise::PasswordsController#create action with the message "Nil location provided. Can't build URI." This error occurred during the password reset process, after the reset instructions email was sent.

Possible Causes

Initially, we considered various potential causes including:

  • Missing or misconfigured email settings in Devise.
  • Incorrectly set default_url_options in the environment configuration files.
  • Missing view templates for the Devise password reset flow.
  • Custom overrides in Devise controllers that could be affecting the URL generation process.
  • Despite ensuring proper configuration in these areas, the error persisted.

Solution

The issue was resolved by adding a specific configuration to the config/initializers/devise.rb file. The solution involved specifying the acceptable navigational formats for Devise responses.

Changes Made

Devise Configuration Update:

In config/initializers/devise.rb, I added the following line:

config.navigational_formats = ['*/*', :html, :turbo_stream]

This defines the acceptable response formats for navigational requests within Devise, including HTML and Turbo Stream (useful if Hotwire’s Turbo Drive is used in the application).

Email Settings Verification:

Although not directly related to the final solution, I ensured that the email settings in Devise were correctly configured. In config/initializers/devise.rb, I verified:

config.mailer_sender = 'my@email.com'

This setting specifies the sender email address for Devise-related emails.

Action Mailer Configuration:

In both config/environments/development.rb and config/environments/production.rb, I checked and confirmed the correct settings for Action Mailer, particularly the default_url_options. This is crucial for generating absolute URLs in emails and responses.

Example for development environment:

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }`

Conclusion

The resolution involved a configuration change in Devise to specify acceptable response formats. This change addressed the issue where Devise was unable to correctly build a URI during the password reset process.

Tags: