{"record":{"id":"d37a9a1f4f7d537c","repo":"SeleniumHQ/selenium","slug":"timed-out-after-timeout-seconds","errorCode":null,"errorMessage":"timed out after #{@timeout} seconds","messagePattern":"timed out after #(.+?) seconds","errorType":"exception","errorClass":"Error::TimeoutError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/common/wait.rb","lineNumber":76,"sourceCode":"            return result if result\n          rescue *@ignored => last_error # rubocop:disable Naming/RescuedExceptionsVariableName\n            # swallowed\n          end\n\n          sleep @interval\n        end\n\n        msg = if @message\n                @message.dup\n              elsif @message_provider\n                @message_provider.call\n              else\n                \"timed out after #{@timeout} seconds\"\n              end\n\n        msg << \" (#{last_error.message})\" if last_error\n\n        raise Error::TimeoutError, msg\n      end\n\n      private\n\n      def current_time\n        Process.clock_gettime(Process::CLOCK_MONOTONIC)\n      end\n    end # Wait\n  end # WebDriver\nend # Selenium\n","sourceCodeStart":58,"sourceCodeEnd":87,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/wait.rb#L58-L87","documentation":"Raised by Selenium::WebDriver::Wait#until when the block does not return a truthy value within the configured :timeout (default 5 seconds). The method polls the block every :interval (default 0.2s); if the end_time is reached without a truthy return, it raises Error::TimeoutError. If a custom :message or :message_provider was supplied, that text is used; otherwise the default 'timed out after N seconds' is shown. If an ignored exception was caught during polling, its message is appended.","triggerScenarios":"Waiting for an element that never appears: Selenium::WebDriver::Wait.new.until { driver.find_element(:id, 'missing') }. Waiting for a page condition that is never met (e.g., a title that doesn't change). The block always returns nil/false. The element exists but find_element raises NoSuchElementError (ignored by default) every poll cycle.","commonSituations":"Page load is slower than the default 5s timeout. Element selectors changed in a UI update so the element is never found. AJAX content that loads conditionally and sometimes doesn't appear. SPA navigation not triggering the expected DOM state.","solutions":["Increase the timeout: Selenium::WebDriver::Wait.new(timeout: 30).until { ... }.","Verify the selector/condition is correct by testing it manually (e.g., inspect the page DOM).","Add a custom message for diagnosis: Wait.new(timeout: 30, message: 'Login button never appeared').until { ... }.","Broaden the set of ignored exceptions if needed: Wait.new(ignore: [NoSuchElementError, StaleElementReferenceError]).until { ... }.","Ensure the block returns a truthy value on success (not just nil from a side-effecting call)."],"exampleFix":"// before\nwait = Selenium::WebDriver::Wait.new  # default 5s\nwait.until { driver.find_element(:id, 'slow-loading-btn') }\n# raises: timed out after 5 seconds (no such element...)\n\n// after\nwait = Selenium::WebDriver::Wait.new(\n  timeout: 30,\n  message: 'Login button did not appear within 30s'\n)\nelement = wait.until { driver.find_element(:id, 'slow-loading-btn') }","handlingStrategy":"try-catch","validationCode":"# Validate preconditions before entering the wait\ndef wait_for_element(driver, how, what, timeout: 30)\n  wait = Selenium::WebDriver::Wait.new(\n    timeout: timeout,\n    message: \"Element #{how}=#{what} not found within #{timeout}s\",\n    ignore: [\n      Selenium::WebDriver::Error::NoSuchElementError,\n      Selenium::WebDriver::Error::StaleElementReferenceError\n    ]\n  )\n  wait.until { driver.find_element(how, what) }\nend","typeGuard":null,"tryCatchPattern":"wait = Selenium::WebDriver::Wait.new(timeout: 30, message: 'Element not found')\nbegin\n  element = wait.until { driver.find_element(:css, '.loaded') }\nrescue Selenium::WebDriver::Error::TimeoutError => e\n  warn \"Wait failed: #{e.message}\"\n  # take a screenshot or snapshot state for debugging\n  driver.save_screenshot('timeout_debug.png')\n  raise\nend","preventionTips":["Set a realistic timeout based on expected page load / AJAX behavior (15-60s for complex SPAs).","Always provide a descriptive :message to the Wait for faster diagnosis.","Include StaleElementReferenceError in the :ignore list for dynamic pages with rapid DOM updates.","Ensure the block returns a truthy value on success — a side-effecting call returning nil will always time out.","Use explicit waits (Wait.until) instead of fixed sleep() calls."],"tags":["wait","timeout","polling","ruby"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}