grafana/k6 · error
parsing wait for selector
Error message
parsing wait for selector %q options: %w
What it means
Thrown while parsing the options object of frame.waitForSelector(selector, options) (browser/frame_mapping.go:461); the selector is echoed via %q. FrameWaitForSelectorOptions.Parse has a hard enum check on state and fails with '"%s" is not a valid DOM state' unless state is exactly one of attached, detached, visible or hidden (common/frame.go domElementStateToID). strict and timeout are coerced and cannot fail.
Solutions
- Use one of the four lowercase states: attached | detached | visible | hidden
- Trim and lowercase dynamic values: state: String(raw).trim().toLowerCase() after validating against the whitelist
- Omit state (defaults to visible)
- Add an early assertion in your script when state comes from external data
Example fix
// before
frame.waitForSelector('#el', { state: 'Visible' });
// after
frame.waitForSelector('#el', { 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(`state must be one of ${DOM_STATES.join('|')}, got '${opts.state}'`);
} Type guard
function isWaitForSelectorOptions(o) {
if (o == null) return true;
return (o.state === undefined || ['attached', 'detached', 'visible', 'hidden'].includes(o.state)) &&
(o.timeout === undefined || typeof o.timeout === 'number');
} Try / catch
try { const h = await frame.waitForSelector(sel, opts); } catch (e) { if (!String(e.message).includes('is not a valid DOM state')) throw e; } Prevention
- Whitelist the four DOM states in a shared constant and validate data-driven values
- Prefer waitForSelector(sel, { state: 'hidden' }) semantics over inventing states like 'gone'
- Trim external strings before using them as enum values
When it happens
Trigger: frame.waitForSelector('#el', { state: 'Visible' }) (wrong casing); { state: 'attached ' } (trailing whitespace); { state: 'displayed' } or 'present' (invented states); state loaded from config with stray characters.
Common situations: Autocomplete-free editors letting casing typos through; translating Selenium expectations (displayed/present) into Playwright-style states; values arriving from CSV/JSON data sources without trimming.
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
- frame waitForFunction
- parsing frame tap options
- parsing frame uncheck options
- parsing text content options
- parsing type options
AI-assisted analysis of grafana/k6@8d06114777 (2026-09-14).
Data as JSON: /api/errors/1472e21eea3ad448.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/frame_mapping.go:459
}), nil
},
"waitForLoadState": func(state string, opts sobek.Value) (*sobek.Promise, error) {
popts, err := parseFrameWaitForLoadStateOptions(rt, opts, f.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing waitForLoadState %q options: %w", state, err)
}
return promise(vu, func() (any, error) {
return nil, f.WaitForLoadState(state, popts) //nolint:wrapcheck
}), nil
},
"waitForNavigation": func(opts sobek.Value) (*sobek.Promise, error) {
return mapWaitForNavigation(rt, vu, f, opts)
},
"waitForSelector": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
popts, err := parseFrameWaitForSelectorOptions(rt, opts, f.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing wait for selector %q options: %w", selector, err)
}
return promise(vu, func() (any, error) {
eh, err := f.WaitForSelector(selector, popts)
if err != nil {
return nil, err //nolint:wrapcheck
}
return mapElementHandle(vu, eh), nil
}), nil
},
"waitForTimeout": func(timeout int64) *sobek.Promise {
return promise(vu, func() (any, error) {
f.WaitForTimeout(timeout)
return nil, nil
})
},
"waitForURL": func(url sobek.Value, opts sobek.Value) (*sobek.Promise, error) {
return mapWaitForURL(rt, vu, f, url, opts)View on GitHub (pinned to 8d06114777)