{"record":{"id":"227459865c2baaa8","repo":"teamcapybara/capybara","slug":"query-failure-message-227459","errorCode":null,"errorMessage":"query.failure_message","messagePattern":"query\\.failure_message","errorType":"exception","errorClass":"Capybara::ExpectationNotMet","httpStatus":null,"severity":"error","filePath":"lib/capybara/session/matchers.rb","lineNumber":24,"sourceCode":"    # Asserts that 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 (path+query by default)\n    #\n    # @!macro current_path_query_params\n    #   @overload $0(string, **options)\n    #     @param string [String]           The string that the current 'path' should equal\n    #   @overload $0(regexp, **options)\n    #     @param regexp [Regexp]           The regexp that the current 'path' should match to\n    #   @option options [Boolean] :url (true if `string` is a full url, otherwise false) Whether the comparison should be done against the full current url or just the path\n    #   @option options [Boolean] :ignore_query (false)  Whether the query portion of the current url/path should be ignored\n    #   @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum time that Capybara will wait for the current url/path to eq/match given string/regexp argument\n    # @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time\n    # @return [true]\n    #\n    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","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/session/matchers.rb#L6-L42","documentation":"Raised by Session#assert_current_path (and the have_current_path matcher) when the browser's current path, or full URL, does not equal or match the expected String/Regexp within the wait time (default Capybara.default_max_wait_time). Capybara retries the comparison until the timer expires, then raises Capybara::ExpectationNotMet carrying the query's failure_message, which shows the expected and actual values.","triggerScenarios":"expect(page).to have_current_path('/dashboard') while the page is still on '/login'; page.assert_current_path(%r{/items/\\d+}) for a record page that has not finished rendering; passing a full URL string (comparison then runs against the full current URL) while the actual query string differs, e.g. '/search?q=1' vs '/search?q=2'.","commonSituations":"Not waiting for asynchronous navigation or a redirect chain after click_button/visit; trailing-slash or query-string mismatches; passing a path but expecting full-URL comparison (or the reverse); slow CI environments where default_max_wait_time is exceeded.","solutions":["Assert the destination right after the action that navigates and rely on the built-in retry; on slow CI extend it with expect(page).to have_current_path('/dashboard', wait: 5).","If the app appends query params you do not care about, add ignore_query: true.","Pass only the path when you want path-only comparison; pass a full URL only when you want full-URL comparison.","For dynamic segments use a Regexp: have_current_path(%r{/items/\\d+})."],"exampleFix":"# before\nexpect(page).to have_current_path('/search') # fails: actual is '/search?q=capybara'\n\n# after\nexpect(page).to have_current_path('/search', ignore_query: true)","handlingStrategy":"retry","validationCode":"# Wait for a landmark of the destination page first, then assert the path\nexpect(page).to have_selector('h1', text: 'Dashboard')\nexpect(page).to have_current_path('/dashboard')","typeGuard":"def on_path?(expected, **opts)\n  expected = expected.to_s\n  current = opts[:ignore_query] ? page.current_path : page.current_url\n  expected.start_with?('http') ? current == expected : current.end_with?(expected)\nend","tryCatchPattern":"begin\n  expect(page).to have_current_path('/dashboard', wait: 2)\nrescue Capybara::ExpectationNotMet\n  retry_count = (defined?(retry_count) ? retry_count : 0) + 1\n  retry if retry_count < 2 # bounded retry for redirect chains on slow CI\n  raise\nend","preventionTips":["Assert current_path immediately after the navigation action so Capybara's built-in wait does the retrying.","Use ignore_query: true whenever the app appends tracking/timestamp query params.","Prefer Regexp with anchors (%r{/items/\\d+}) over exact strings for dynamic routes.","Set Capybara.default_max_wait_time high enough for the slowest CI environment."],"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"}