SeleniumHQ/selenium · error · Error

Element must not be null. Please provide a valid <select> el

Error message

Element must not be null. Please provide a valid <select> element.

What it means

Thrown synchronously by the Select constructor when the element argument is strictly null. Note the guard is `=== null` only — undefined, 0, '' or other falsy non-null values are NOT caught here and will instead blow up later on this.element.getAttribute. This is a generic Error, not a WebDriver protocol error.

Source

Thrown at javascript/selenium-webdriver/lib/select.js:150

   * element, and not merely by counting.
   *
   * @param {Number} index The option at this index will be deselected
   * @return {Promise<void>}
   */
  deselectByIndex(index) {} // eslint-disable-line
}

/**
 * @implements ISelect
 */
class Select {
  /**
   * Create an Select Element
   * @param {WebElement} element Select WebElement.
   */
  constructor(element) {
    if (element === null) {
      throw new Error(`Element must not be null. Please provide a valid <select> element.`)
    }

    this.element = element

    this.element.getAttribute('tagName').then(function (tagName) {
      if (tagName.toLowerCase() !== 'select') {
        throw new Error(`Select only works on <select> elements`)
      }
    })

    this.element.getAttribute('multiple').then((multiple) => {
      this.multiple = multiple !== null && multiple !== 'false'
    })
  }

  /**
   *
   * Select option with specified index.

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Resolve the element with driver.findElement(by) which throws NoSuchElementError if absent, then pass that WebElement.
  2. If using findElements (plural), take the first element and check before constructing: const [el] = await driver.findElements(by); if (!el) throw new Error('no select');
  3. Ensure the variable is actually a WebElement and not a null from an earlier failed lookup.
  4. Replace null-returning helpers with ones that throw or return undefined, then guard explicitly.

Example fix

// before
const el = await tryFind(by); // returns null on miss
const sel = new Select(el); // throws

// after
const el = await driver.findElement(by); // throws NoSuchElementError naturally
const sel = new Select(el);
Defensive patterns

Strategy: validation

Validate before calling

async function makeSelect(locator) {
  const el = await driver.findElement(locator); // throws NoSuchElementError if absent
  if (!el) throw new Error('select element not found');
  return new Select(el);
}

Type guard

function isWebElement(el, WebElement) {
  return el instanceof WebElement;
}

Try / catch

try {
  return new Select(maybeNull);
} catch (e) {
  if (/Element must not be null/.test(e.message)) {
    const el = await driver.findElement(locator);
    return new Select(el);
  }
  throw e;
}

Prevention

When it happens

Trigger: new Select(null); passing the result of an await that resolved to null because the locator chain returned nothing; driver.findElement in a try that swallowed the NoSuchElementError and returned null.

Common situations: Wrapper code that returns null 'not found'; refactoring away an exception into a null return; defensive code that assumes findElement can return null (it cannot — it throws).

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/1e78f71c61950315. Report an issue: GitHub.