grafana/k6 · error
parsing get attribute options: %w
Error message
parsing get attribute options: %w
What it means
Thrown when locator.getAttribute(name, opts) cannot parse its second argument into FrameBaseOptions (accepted keys: strict boolean, timeout number in milliseconds). The mapping layer wraps the Parse failure as 'parsing get attribute options: <cause>' so the exception names the failing API. In current k6 the underlying FrameBaseOptions.Parse is lenient (unknown keys ignored, values coerced via ToBoolean/ToInteger), so this wrap is mostly defensive; it fires when the opts slot gets something that is not a valid options shape, especially on k6 versions with stricter option parsing.
Source
Thrown at internal/js/modules/k6/browser/browser/locator_mapping.go:221
}))
},
"first": func() *sobek.Object {
ml := mapLocator(vu, lo.First())
return rt.ToValue(ml).ToObject(rt)
},
"focus": func(opts sobek.Value) (*sobek.Promise, error) {
copts := common.NewFrameBaseOptions(lo.Timeout())
if err := copts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing focus options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, lo.Focus(copts) //nolint:wrapcheck
}), nil
},
"getAttribute": func(name string, opts sobek.Value) (*sobek.Promise, error) {
copts := common.NewFrameBaseOptions(lo.Timeout())
if err := copts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing get attribute options: %w", err)
}
return promise(vu, func() (any, error) {
s, ok, err := lo.GetAttribute(name, copts)
if err != nil {
return nil, err //nolint:wrapcheck
}
if !ok {
return nil, nil
}
return s, nil
}), nil
},
"getByAltText": func(alt sobek.Value, opts sobek.Value) (*sobek.Object, error) {
if k6common.IsNullish(alt) {
return nil, errors.New("missing required argument 'altText'")
}
palt, popts := parseGetByBaseOptions(vu.Context(), alt, false, opts)
View on GitHub (pinned to 93accf6570)
Solutions
- Pass options as a plain object: locator.getAttribute('href', { timeout: 30000 }) — timeout in milliseconds as a number, or omit the second argument entirely
- Check argument order: getAttribute(name, opts); a string like '30s' in the opts slot is never valid
- If you only need a timeout, set it once via locator.setDefaultTimeout() or page.setDefaultTimeout() instead of per-call options
- Upgrade to the latest k6 so unknown/loosely-typed keys are coerced or ignored rather than rejected
Example fix
// before
const href = await page.locator('a.link').getAttribute('href', '30s');
// after
const href = await page.locator('a.link').getAttribute('href', { timeout: 30000 }); Defensive patterns
Strategy: validation
Validate before calling
function assertGetAttributeOpts(opts) {
if (opts === null || opts === undefined) return;
if (typeof opts !== 'object' || Array.isArray(opts)) {
throw new TypeError('getAttribute options must be a plain object');
}
if ('timeout' in opts && (typeof opts.timeout !== 'number' || !Number.isFinite(opts.timeout))) {
throw new TypeError('getAttribute timeout must be a number of milliseconds');
}
} Type guard
function isLocatorBaseOptions(v) {
if (v === null || v === undefined) return true;
if (typeof v !== 'object' || Array.isArray(v)) return false;
return (v.timeout === undefined || typeof v.timeout === 'number') &&
(v.strict === undefined || typeof v.strict === 'boolean');
} Try / catch
try {
const href = await locator.getAttribute('href', opts);
} catch (e) {
if (/parsing get attribute options/.test(String(e.message))) {
throw new Error(`Invalid options passed to locator.getAttribute: ${JSON.stringify(opts)}`);
}
throw e;
} Prevention
- Always pass option objects as literals with numeric millisecond timeouts
- Keep a shared typed helper for building { timeout } objects so every locator call uses the same shape
- Lint against duration strings ('5s') in browser module calls
When it happens
Trigger: Calling page.locator('a').getAttribute('href', opts) with a non-object in the options slot, e.g. getAttribute('href', '30s') or getAttribute('href', 30000); or passing a wrong-typed timeout/strict under a strict parser. Playwright's getAttribute takes no options object, so ported scripts sometimes pass extra positional arguments that land here.
Common situations: Porting Playwright scripts and passing a timeout string instead of an options object; argument-order mistakes (selector in the opts slot); upgrading/downgrading k6 browser module versions whose parser rejects wrong field types instead of coercing them.
Related errors
- parsing inner HTML options: %w
- parsing inner text options: %w
- parsing text content options: %w
- parsing input value options: %w
- parsing select option options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/059b216195916d8f.
Report an issue: GitHub.