{"record":{"id":"cb01b63c8a27f573","repo":"teamcapybara/capybara","slug":"query-negative-failure-message-cb01b6","errorCode":null,"errorMessage":"query.negative_failure_message","messagePattern":"query\\.negative_failure_message","errorType":"exception","errorClass":"Capybara::ExpectationNotMet","httpStatus":null,"severity":"error","filePath":"lib/capybara/session/matchers.rb","lineNumber":40,"sourceCode":"    def assert_current_path(path, **options, &optional_filter_block)\n      _verify_current_path(path, optional_filter_block, **options) do |query|\n        raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)\n      end\n    end\n\n    ##\n    # Asserts that the page doesn't have the given path.\n    # By default, if passed a full url this will compare against the full url,\n    # if passed a path only the path+query portion will be compared, if passed a regexp\n    # the comparison will depend on the :url option\n    #\n    # @macro current_path_query_params\n    # @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time\n    # @return [true]\n    #\n    def assert_no_current_path(path, **options, &optional_filter_block)\n      _verify_current_path(path, optional_filter_block, **options) do |query|\n        raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self)\n      end\n    end\n\n    ##\n    # Checks if the page has the given path.\n    # By default, if passed a full url this will compare against the full url,\n    # if passed a path only the path+query portion will be compared, if passed a regexp\n    # the comparison will depend on the :url option\n    #\n    # @macro current_path_query_params\n    # @return [Boolean]\n    #\n    def has_current_path?(path, **options, &optional_filter_block)\n      make_predicate(options) { assert_current_path(path, **options, &optional_filter_block) }\n    end\n\n    ##\n    # Checks if the page doesn't have the given path.","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/session/matchers.rb#L22-L58","documentation":"Raised by Session#assert_no_current_path (and the have_no_current_path matcher) when the current path or URL STILL equals/matches the given String/Regexp after the wait time expires. It is the negative expectation: Capybara polls until the path stops resolving, and if it never does, raises Capybara::ExpectationNotMet with the query's negative_failure_message.","triggerScenarios":"expect(page).to have_no_current_path('/login') after a login-submit that should navigate away, but the page stays on '/login'; page.assert_no_current_path(%r{/}) where the regexp matches every path, so it can never stop matching.","commonSituations":"Logout or redirect flows where navigation never fires (JS error, prevented submit); overly broad regexps such as %r{/} that match any path; asserting the negative before the navigating action has been performed; single-page apps that change content without changing the path.","solutions":["Make sure the action that navigates away (click_link/click_button) has run before the negative assertion, so the matcher's polling observes the change.","Tighten an over-broad Regexp: assert_no_current_path('/login') or a specific %r{\\A/login\\z} instead of %r{/}.","Extend the wait for slow redirects: have_no_current_path('/login', wait: 5).","If the path is genuinely expected to stay, invert the assertion to have_current_path and assert on content changes instead."],"exampleFix":"# before\nexpect(page).to have_no_current_path(%r{/}) # always matches every path -> always raises\n\n# after\nexpect(page).to have_no_current_path('/login')","handlingStrategy":"retry","validationCode":"# Trigger and confirm the navigation first, then assert the negative\nclick_button 'Log out'\nexpect(page).to have_selector('.flash', text: 'Signed out')\nexpect(page).to have_no_current_path('/login')","typeGuard":"def still_on_path?(expected)\n  page.current_path == expected || page.current_path.match?(expected.is_a?(Regexp) ? expected : /\\A#{Regexp.escape(expected)}\\z/)\nend","tryCatchPattern":"begin\n  expect(page).to have_no_current_path('/login', wait: 2)\nrescue Capybara::ExpectationNotMet\n  # The navigation never happened; re-trigger it once, then retry the assertion\n  click_button 'Log out' if page.has_button?('Log out')\n  retry\nend","preventionTips":["Never assert no_current_path before performing the action that should navigate away.","Avoid over-broad regexps like %r{/}; they match every path and make the negative assertion unsatisfiable.","For SPAs that keep the path and swap content, assert on disappearing content (have_no_selector) instead of the path.","Include a wait budget (wait: n) on negative path assertions in redirect-heavy flows."],"tags":["capybara","rspec","assertion","navigation","minitest"],"backgroundTag":"assertion-timeout","analyzedSha":"15b5fdb76e972e9623d5af2123ed3755594f9732","analyzedAt":"2026-08-21T16:53:45.588Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}