grafana/k6 · error

parsing waitForSelector

Error message

parsing waitForSelector %q options: %w

What it means

Thrown when ElementHandle.waitForSelector cannot parse its options. FrameWaitForSelectorOptions.Parse validates the state key against exactly four allowed values — attached, detached, visible, hidden — and returns '%q is not a valid DOM state' for anything else; timeout/strict are coerced and unknown keys ignored. Playwright-only states like enabled, disabled, stable or editable are therefore rejected here.

Solutions

  1. Use one of the supported states: attached, detached, visible or hidden
  2. To wait for enabled/disabled semantics, waitForSelector with state 'visible' plus an evaluate()-based predicate
  3. Check the error text — it quotes the exact rejected state string

Example fix

// before
await handle.waitForSelector('#submit', { state: 'enabled' });
// after
await handle.waitForSelector('#submit', { state: 'visible' });
Defensive patterns

Strategy: validation

Validate before calling

const DOM_STATES = ['attached', 'detached', 'visible', 'hidden'];
if (opts?.state !== undefined && !DOM_STATES.includes(opts.state)) {
  throw new Error(`invalid state '${opts.state}'; allowed: ${DOM_STATES.join(', ')}`);
}
await handle.waitForSelector(selector, opts);

Type guard

function isDOMElementState(v) {
  return ['attached', 'detached', 'visible', 'hidden'].includes(v);
}

Try / catch

try {
  await handle.waitForSelector(sel, opts);
} catch (e) {
  if (String(e).includes('parsing waitForSelector') && String(e).includes('not a valid DOM state')) {
    await handle.waitForSelector(sel, { ...opts, state: 'visible' });
  } else { throw e; }
}

Prevention

When it happens

Trigger: waitForSelector('#el', {state: 'enabled'}), {state: 'stable'} or a typo like {state: 'visable'} — any state string outside attached|detached|visible|hidden.

Common situations: Copying Playwright examples that use state: 'enabled'/'disabled'; assuming the full Playwright state enum exists in the k6 browser module.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-09-14). Data as JSON: /api/errors/a864cafc81a01ae1. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/element_handle_mapping.go:301

				return nil, fmt.Errorf("parsing uncheck options: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, eh.Uncheck(popts) //nolint:wrapcheck
			}), nil
		},
		"waitForElementState": func(state string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseElementHandleWaitForElementStateOptions(rt, opts, eh.DefaultTimeout())
			if err != nil {
				return nil, fmt.Errorf("parsing waitForElementState options: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, eh.WaitForElementState(state, popts) //nolint:wrapcheck
			}), nil
		},
		"waitForSelector": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameWaitForSelectorOptions(rt, opts, eh.DefaultTimeout())
			if err != nil {
				return nil, fmt.Errorf("parsing waitForSelector %q options: %w", selector, err)
			}
			return promise(vu, func() (any, error) {
				eh, err := eh.WaitForSelector(selector, popts)
				if err != nil {
					return nil, err //nolint:wrapcheck
				}
				return mapElementHandle(vu, eh), nil
			}), nil
		},
	}
	maps["$"] = func(selector string) *sobek.Promise {
		return promise(vu, func() (any, error) {
			eh, err := eh.Query(selector, common.StrictModeOff)
			if err != nil {
				return nil, err //nolint:wrapcheck
			}
			// ElementHandle can be null when the selector does not match any elements.
			// We do not want to map nil elementHandles since the expectation is a

View on GitHub (pinned to 3fcf5388d7)