{"record":{"id":"43e5206d71273f1d","repo":"SeleniumHQ/selenium","slug":"you-may-not-select-a-disabled-option-43e520","errorCode":null,"errorMessage":"You may not select a disabled option","messagePattern":"You may not select a disabled option","errorType":"exception","errorClass":"Error::UnsupportedOperationError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/support/select.rb","lineNumber":218,"sourceCode":"          opts = find_by_value value\n\n          return deselect_options(opts) unless opts.empty?\n\n          raise Error::NoSuchElementError, \"cannot locate option with value: #{value.inspect}\"\n        end\n\n        def deselect_by_index(index)\n          raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?\n\n          opts = find_by_index index\n\n          return deselect_option(opts.first) unless opts.empty?\n\n          raise Error::NoSuchElementError, \"cannot locate option with index: #{index}\"\n        end\n\n        def select_option(option)\n          raise Error::UnsupportedOperationError, 'You may not select a disabled option' unless option.enabled?\n\n          option.click unless option.selected?\n        end\n\n        def deselect_option(option)\n          option.click if option.selected?\n        end\n\n        def select_options(opts)\n          if multiple?\n            opts.each { |o| select_option o }\n          else\n            select_option opts.first\n          end\n        end\n\n        def deselect_options(opts)\n          if multiple?","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/support/select.rb#L200-L236","documentation":"Selenium::WebDriver::Support::Select#select_option raises UnsupportedOperationError with the message 'You may not select a disabled option' when the target <option> reports option.enabled? == false (i.e. it carries the HTML disabled attribute). The guard exists because clicking a disabled option cannot change the control's state and browsers either ignore the click or raise their own error, so Selenium fails fast with a clear, language-level message rather than a flaky DOM interaction. The same path is reached by every public selector: select_by(...), select_options, and multi-select iteration all funnel through select_option. It is an operation-level guard, not a transport error, so it surfaces synchronously in the calling Ruby thread.","triggerScenarios":"Calling select.select_by(:text, 'X'), select.select_by(:value, 'Y'), select.select_by(:index, N), or select.all_options.each { |o| select.select_option(o) } where the resolved option element has disabled=\"disabled\". Also triggered indirectly when select_options iterates a multi-select whose matched opts array contains at least one disabled option, since opts.each { |o| select_option o } will hit the disabled one and abort the whole batch without selecting the rest.","commonSituations":"Forms whose options are disabled by the application based on permissions or other field state; placeholder/empty options marked disabled that a test tries to pick by index 0; options disabled via JS until a checkbox is ticked; selecting an option whose text matches a disabled duplicate; CI running before the page finishes enabling options after an AJAX round-trip.","solutions":["Before selecting, assert/wait for the specific option to be enabled: wait.until { select.options.find { |o| o.value == v && o.enabled? } }, then select it.","Pick a different enabled option that satisfies the test intent instead of the disabled one (e.g. the first enabled option).","If the option is expected to be enabled, fix the precondition first: tick the controlling checkbox, dismiss the modal, or wait for the AJAX call that removes the disabled attribute.","As a last resort only, if the test legitimately needs to force a disabled option, remove the attribute via execute_script and re-select, but treat this as a test smell since it diverges from real user behavior."],"exampleFix":"# before\nselect = Selenium::WebDriver::Support::Select.new(el)\nselect.select_by(:value, 'restricted')   # raises UnsupportedOperationError if disabled\n\n# after\nopt = select.options.find { |o| o.value == 'restricted' }\nwait.until { opt&.enabled? }\nselect.select_by(:value, 'restricted')","handlingStrategy":"validation","validationCode":"# Run before calling select.select_by(...)\nrequire 'selenium/webdriver'\n\ndef safe_select(select, by:, value:)\n  opt = case by\n        when :text  then select.options.find { |o| o.text == value }\n        when :value then select.options.find { |o| o.value == value }\n        when :index then select.options[value]\n        end\n  raise ArgumentError, \"no option for #{by}=#{value.inspect}\" unless opt\n  raise Selenium::WebDriver::Error::UnsupportedOperationError, \\\n        \"option #{by}=#{value.inspect} is disabled\" unless opt.enabled?\n  select.select_option(opt)\nend\n\n# With a wait for AJAX-enabled options:\nwait = Selenium::WebDriver::Wait.new(timeout: 10)\nwait.until do\n  opt = select.options.find { |o| o.value == 'restricted' }\n  opt && opt.enabled?\nend\nselect.select_by(:value, 'restricted')","typeGuard":"# Ruby has no static types; emulate a guard proc to narrow an option element.\ndef selectable_option?(option)\n  option.is_a?(Selenium::WebDriver::Element) &&\n    option.enabled? &&\n    option.tag_name.casecmp('option').zero?\nend\n\nraise 'not selectable' unless selectable_option?(opt)","tryCatchPattern":"begin\n  select.select_by(:value, 'restricted')\nrescue Selenium::WebDriver::Error::UnsupportedOperationError => e\n  raise unless e.message.include?('disabled option')\n  # the target option is disabled: pick the first enabled option or fail the test explicitly\n  enabled = select.options.select(&:enabled?).reject(&:selected?)\n  raise 'no enabled options to select' if enabled.empty?\n  select.select_option(enabled.first)\nend","preventionTips":["Never select by index 0 blindly; placeholder options are frequently disabled.","Add a Selenium::WebDriver::Wait that checks option.enabled? (not just option.displayed?) before selecting.","For multi-select, filter opts.select(&:enabled?) before iterating, since select_options aborts the batch on the first disabled option.","In tests, assert the expected precondition (option enabled) as an explicit step so failures point at the page state, not at the select call."],"tags":["ruby","selenium","webdriver","forms","select","validation"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}