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
- Use one of the supported states: attached, detached, visible or hidden
- To wait for enabled/disabled semantics, waitForSelector with state 'visible' plus an evaluate()-based predicate
- 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
- Whitelist the four supported states in a shared constant
- Do not assume Playwright's enabled/disabled/stable states exist in k6
- Test waitForSelector option handling early in script development to catch enum mismatches cheaply
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
- checking hit target
- getting element position
- getting injected script
- getting original viewport size
- getting text content of element: unexpected type %T…
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 aView on GitHub (pinned to 3fcf5388d7)