SeleniumHQ/selenium · error · Error::UnsupportedOperationError
You may not select a disabled option
Error message
You may not select a disabled option
What it means
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.
Source
Thrown at rb/lib/selenium/webdriver/support/select.rb:218
opts = find_by_value value
return deselect_options(opts) unless opts.empty?
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
end
def deselect_by_index(index)
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
opts = find_by_index index
return deselect_option(opts.first) unless opts.empty?
raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
end
def select_option(option)
raise Error::UnsupportedOperationError, 'You may not select a disabled option' unless option.enabled?
option.click unless option.selected?
end
def deselect_option(option)
option.click if option.selected?
end
def select_options(opts)
if multiple?
opts.each { |o| select_option o }
else
select_option opts.first
end
end
def deselect_options(opts)
if multiple?View on GitHub (pinned to aa36b38e69)
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.
Example fix
# before
select = Selenium::WebDriver::Support::Select.new(el)
select.select_by(:value, 'restricted') # raises UnsupportedOperationError if disabled
# after
opt = select.options.find { |o| o.value == 'restricted' }
wait.until { opt&.enabled? }
select.select_by(:value, 'restricted') Defensive patterns
Strategy: validation
Validate before calling
# Run before calling select.select_by(...)
require 'selenium/webdriver'
def safe_select(select, by:, value:)
opt = case by
when :text then select.options.find { |o| o.text == value }
when :value then select.options.find { |o| o.value == value }
when :index then select.options[value]
end
raise ArgumentError, "no option for #{by}=#{value.inspect}" unless opt
raise Selenium::WebDriver::Error::UnsupportedOperationError, \
"option #{by}=#{value.inspect} is disabled" unless opt.enabled?
select.select_option(opt)
end
# With a wait for AJAX-enabled options:
wait = Selenium::WebDriver::Wait.new(timeout: 10)
wait.until do
opt = select.options.find { |o| o.value == 'restricted' }
opt && opt.enabled?
end
select.select_by(:value, 'restricted') Type guard
# Ruby has no static types; emulate a guard proc to narrow an option element.
def selectable_option?(option)
option.is_a?(Selenium::WebDriver::Element) &&
option.enabled? &&
option.tag_name.casecmp('option').zero?
end
raise 'not selectable' unless selectable_option?(opt) Try / catch
begin
select.select_by(:value, 'restricted')
rescue Selenium::WebDriver::Error::UnsupportedOperationError => e
raise unless e.message.include?('disabled option')
# the target option is disabled: pick the first enabled option or fail the test explicitly
enabled = select.options.select(&:enabled?).reject(&:selected?)
raise 'no enabled options to select' if enabled.empty?
select.select_option(enabled.first)
end Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- unexpected tag name #{tag_name.inspect}
- Params must be an instance of CookieFilter. Received:'${cook
- Element must not be null. Please provide a valid <select> el
- Index needs to be 0 or any other positive number
- You may only deselect options of a multi-select
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/43e5206d71273f1d.
Report an issue: GitHub.