{"record":{"id":"5cb3c0804cb51de5","repo":"heartcombo/devise","slug":"could-not-find-devise-mapping-for-path-request-f","errorCode":null,"errorMessage":"Could not find devise mapping for path #{request.fullpath.inspect}.\nThis may happen for two reasons:\n\n1) You forgot to wrap your route inside the scope block. For example:\n\n  devise_scope :user do\n    get \"/some/route\" => \"some_devise_controller\"\n  end\n\n2) You are testing a Devise controller bypassing the router.\n   If so, you can explicitly tell Devise which mapping to use:\n\n   @request.env[\"devise.mapping\"] = Devise.mappings[:user]\n\n","messagePattern":"Could not find devise mapping for path #(.+?)\\.\nThis may happen for two reasons:\n\n1\\) You forgot to wrap your route inside the scope block\\. For example:\n\n  devise_scope :user do\n    get \"/some/route\" => \"some_devise_controller\"\n  end\n\n2\\) You are testing a Devise controller bypassing the router\\.\n   If so, you can explicitly tell Devise which mapping to use:\n\n   @request\\.env\\[\"devise\\.mapping\"\\] = Devise\\.mappings\\[:user\\]\n\n","errorType":"exception","errorClass":"AbstractController::ActionNotFound","httpStatus":404,"severity":"error","filePath":"app/controllers/devise_controller.rb","lineNumber":104,"sourceCode":"    get \"/some/route\" => \"some_devise_controller\"\n  end\n\n2) You are testing a Devise controller bypassing the router.\n   If so, you can explicitly tell Devise which mapping to use:\n\n   @request.env[\"devise.mapping\"] = Devise.mappings[:user]\n\nMESSAGE\n  end\n\n  # Returns real navigational formats which are supported by Rails\n  def navigational_formats\n    @navigational_formats ||= Devise.navigational_formats.select { |format| Mime::EXTENSION_LOOKUP[format.to_s] }\n  end\n\n  def unknown_action!(msg)\n    logger.debug \"[Devise] #{msg}\" if logger\n    raise AbstractController::ActionNotFound, msg\n  end\n\n  # Sets the resource creating an instance variable\n  def resource=(new_resource)\n    instance_variable_set(:\"@#{resource_name}\", new_resource)\n  end\n\n  # Helper for use in before_actions where no authentication is required.\n  #\n  # Example:\n  #   before_action :require_no_authentication, only: :new\n  def require_no_authentication\n    assert_is_devise_resource!\n    return unless is_navigational_format?\n    no_input = devise_mapping.no_input_strategies\n\n    authenticated = if no_input.present?\n      args = no_input.dup.push scope: resource_name","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/heartcombo/devise/blob/372b295fe6f63b4af3269f5dcd51a18c0bc2016c/app/controllers/devise_controller.rb#L86-L122","documentation":"Every Devise controller derives its resource scope (User, Admin, etc.) from request.env[\"devise.mapping\"], which is set by the routing scope that devise_for/devise_scope installs. DeviseController runs assert_is_devise_resource! as a prepend_before_action on every request, and when the mapping env entry is nil it raises AbstractController::ActionNotFound with this message. In practice it means a Devise controller action was reached outside of any Devise-mapped route, or a controller test hit the controller directly without bypassing the router being compensated for.","triggerScenarios":"1) Routing a custom endpoint straight to a Devise controller, e.g. get \"/users/invite\" => \"devise/registrations#invite\", outside a devise_scope :user block, so the mapping middleware never runs. 2) Request/controller specs on a Devise controller that call get :new, params: {} directly (bypassing the router) without first setting @request.env[\"devise.mapping\"] = Devise.mappings[:user]. 3) Reusing a Devise controller subclass for a non-Devise route that was never wrapped in devise_scope.","commonSituations":"Adding custom actions to Devise controllers (invite flows, profile pages) and mounting them with plain routes; writing controller tests for Devise or inherited Devise controllers instead of request/integration specs; refactoring routes.rb and accidentally moving a Devise route out of its scope; namespaced engines routing to Devise controllers without re-declaring the scope.","solutions":["Wrap the offending route in a devise_scope block: devise_scope :user do get \"/users/invite\" => \"devise/registrations#invite\" end (use the scope name from devise_for).","If this happens in a controller/request spec, set the mapping explicitly in setup/before: @request.env[\"devise.mapping\"] = Devise.mappings[:user].","If the route is genuinely custom logic, point it at your own controller that inherits from the Devise controller only when it is also mounted inside devise_scope; otherwise inherit from ApplicationController.","Prefer request specs (rails generate rspec:request or Rails' integration tests) that go through the real router, which sets the mapping automatically."],"exampleFix":"# before (config/routes.rb)\nget \"/users/invite\" => \"devise/registrations#invite\"\n\n# after\nscope \"/users\" do\n  devise_scope :user do\n    get \"/invite\" => \"devise/registrations#invite\", as: :invite\n  end\nend\n\n# spec fix (controller specs bypassing the router)\n# before\nRSpec.describe Devise::RegistrationsController, type: :controller do\n  describe \"GET #new\" do\n    it \"renders\" do\n      get :new\n    end\n  end\nend\n\n# after\nRSpec.describe Devise::RegistrationsController, type: :controller do\n  before do\n    @request.env[\"devise.mapping\"] = Devise.mappings[:user]\n  end\n  describe \"GET #new\" do\n    it \"renders\" do\n      get :new\n      expect(response).to have_http_status(:ok)\n    end\n  end\nend","handlingStrategy":"validation","validationCode":"# In a custom Devise controller, verify the mapping before relying on it:\nclass Devise::RegistrationsController\n  protected\n\n  def devise_mapping_present?\n    request.env[\"devise.mapping\"].present?\n  end\nend\n\n# In controller specs, always install the mapping in before/setup so the\n# prepend_before_action assert_is_devise_resource! never fires:\n# @request.env[\"devise.mapping\"] = Devise.mappings[:user]","typeGuard":"# Predicate usable as a before_action guard for custom Devise routes:\ndef devise_scope_mapped?(request)\n  !request.env[\"devise.mapping\"].nil?\nend\n# usage: before_action -> { head :not_found unless devise_scope_mapped?(request) }","tryCatchPattern":null,"preventionTips":["Always mount custom routes that target Devise controllers inside devise_scope <resource> in config/routes.rb.","In controller specs for Devise controllers, set @request.env[\"devise.mapping\"] = Devise.mappings[:user] in a before block — or prefer request specs that exercise the real router.","After any routes.rb refactor, hit one Devise route per scope in a smoke test so a missing mapping surfaces in CI, not production.","Use the devise_mapping view/controller helper to inspect which scope a request resolved to when debugging."],"tags":["devise","rails","routing","controller-tests","authentication"],"backgroundTag":"devise-mapping-not-found","analyzedSha":"372b295fe6f63b4af3269f5dcd51a18c0bc2016c","analyzedAt":"2026-08-21T11:55:31.116Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}