grafana/k6 · error
parsing wait for options: %w
Error message
parsing wait for options: %w
What it means
Thrown when locator.waitFor(opts) fails to parse options into FrameWaitForSelectorOptions. This is a live, strict error path for the state key: only 'attached', 'detached', 'visible', 'hidden' are accepted, and anything else returns '<state> is not a valid DOM state', wrapped as 'parsing wait for options: ...'. Also accepted: strict boolean and timeout number in ms (coerced leniently).
Source
Thrown at internal/js/modules/k6/browser/browser/locator_mapping.go:427
return nil, fmt.Errorf("parsing locator tap options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, lo.Tap(copts) //nolint:wrapcheck
}), nil
},
"dispatchEvent": func(typ string, eventInit, opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameDispatchEventOptions(lo.DefaultTimeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing locator dispatch event options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, lo.DispatchEvent(typ, exportArg(eventInit), popts) //nolint:wrapcheck
}), nil
},
"waitFor": func(opts sobek.Value) (*sobek.Promise, error) {
copts := common.NewFrameWaitForSelectorOptions(lo.Timeout())
if err := copts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing wait for options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, lo.WaitFor(copts) //nolint:wrapcheck
}), nil
},
}
}
func parseLocatorOptions(rt *sobek.Runtime, opts sobek.Value) *common.LocatorOptions {
if k6common.IsNullish(opts) {
return nil
}
var popts common.LocatorOptions
obj := opts.ToObject(rt)
for _, k := range obj.Keys() {
switch k {View on GitHub (pinned to 93accf6570)
Solutions
- Use one of the four valid states: waitFor({ state: 'visible' }) — attached, detached, visible, hidden
- Lowercase the state string exactly
- Pass the selector to locator(), not to waitFor — the opts slot accepts only state/strict/timeout
- Set timeout numerically in ms alongside the state
Example fix
// before
await page.locator('.toast').waitFor({ state: 'Shown' });
// after
await page.locator('.toast').waitFor({ state: 'visible', timeout: 5000 }); Defensive patterns
Strategy: validation
Validate before calling
const WAIT_FOR_STATES = new Set(['attached', 'detached', 'visible', 'hidden']);
function assertWaitForOpts(opts) {
if (opts === null || opts === undefined) return;
if (typeof opts !== 'object' || Array.isArray(opts)) {
throw new TypeError('waitFor options must be a plain object');
}
if ('state' in opts && !WAIT_FOR_STATES.has(opts.state)) {
throw new TypeError(`waitFor state must be one of ${[...WAIT_FOR_STATES].join(', ')}, got ${JSON.stringify(opts.state)}`);
}
if ('timeout' in opts && typeof opts.timeout !== 'number') {
throw new TypeError('waitFor timeout must be a number (ms)');
}
} Type guard
function isWaitForOptions(v) {
if (v === null || v === undefined) return true;
if (typeof v !== 'object' || Array.isArray(v)) return false;
const stateOk = v.state === undefined ||
['attached', 'detached', 'visible', 'hidden'].includes(v.state);
return stateOk && (v.timeout === undefined || typeof v.timeout === 'number');
} Try / catch
try {
await locator.waitFor(opts);
} catch (e) {
if (/is not a valid DOM state/.test(String(e.message))) {
throw new Error(`waitFor state must be attached|detached|visible|hidden: ${e.message}`);
}
throw e;
} Prevention
- Whitelist state strings against attached/detached/visible/hidden before the call
- Lowercase state values exactly; 'Visible' is rejected
- Pass the selector to locator(), never to waitFor()
When it happens
Trigger: waitFor({ state: 'shown' }) or { state: 'displayed' } — not valid state names; case errors like { state: 'Visible' }; passing a selector string into the opts slot: waitFor('#id').
Common situations: Translating wait conditions from other frameworks (Selenium's visibility wording, Cypress should('be.visible')); typos and case mismatches; expecting k6 to accept Playwright's full waitForSelector option set (e.g. polling keys are not read here).
Related errors
- parsing get attribute options: %w
- parsing inner HTML options: %w
- parsing inner text options: %w
- parsing text content options: %w
- parsing input value options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/bfe969e0c680cb8d.
Report an issue: GitHub.