grafana/k6 · error
options: expected string or object, got %T
Error message
options: expected string or object, got %T
What it means
Thrown by ConvertSelectOptionValues while iterating array items passed to selectOption (Page/Frame/Locator/ElementHandle). Each item must be either a string (matches value or label) or a plain object (common.SelectOption with value/label/index). Any other item type hits the default branch in browser/mapping.go:83 and aborts selection.
Solutions
- Convert numeric items to strings before the call: values.map(String).
- Wrap non-string items in an option object: { value: String(item) }.
- Filter out null/undefined items: values.filter(v => v != null).
- Validate each item with typeof before calling selectOption.
Example fix
// before
await page.selectOption('#size', data.sizes); // data.sizes = [1, 2, 3]
// after
await page.selectOption('#size', data.sizes.map(String)); Defensive patterns
Strategy: type-guard
Validate before calling
const items = values.filter(v => v != null).map(v => typeof v === 'string' || typeof v === 'object' ? v : String(v));
await page.selectOption('#sel', items); Type guard
function isSelectOptionItem(i) {
if (typeof i === 'string') return true;
if (i == null || typeof i !== 'object' || Array.isArray(i)) return false;
return Object.keys(i).every(k => ['value', 'label', 'index'].includes(k));
} Try / catch
try { await page.selectOption('#sel', values); } catch (e) { if (/expected string or object/.test(e.message)) { /* map offending items to strings and retry */ } throw e; } Prevention
- Map numeric option values to strings at the data boundary.
- Filter null/undefined out of option arrays before calling selectOption.
- Define a shared normalizer (string | {value|label|index}) and use it everywhere.
When it happens
Trigger: page.selectOption('#sel', [1, 2]) (numbers), [true] (booleans), [null] (nullish item), or [() => {}] (functions). Each array item must be 'red', { value: 'red' }, { label: 'Red' }, or { index: 2 }.
Common situations: Option lists read from a JSON data file where numeric values were not quoted (["1","2"] vs [1,2]); mixed arrays built by pushing DOM text that occasionally parses to a number; stale schema where the API started returning integers for option values.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- options: expected array, got %T
- options: expected object, got %T
- options: unsupported type %T
- options[ ]: expected int, got %T
- options[ ]: expected string, got %T
AI-assisted analysis of grafana/k6@8d06114777 (2026-08-18).
Data as JSON: /api/errors/0ac4220db25bd658.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/browser/mapping.go:91
for _, item := range sl {
switch item := item.(type) {
case string:
// Strings will match values or labels
valOpt := common.SelectOption{Value: new(string)}
*valOpt.Value = item
labelOpt := common.SelectOption{Label: new(string)}
*labelOpt.Label = item
opts = append(opts, &valOpt, &labelOpt)
case map[string]any:
opt, err := extractSelectOptionFromMap(item)
if err != nil {
return nil, err
}
opts = append(opts, opt)
default:
return nil, fmt.Errorf("options: expected string or object, got %T", item)
}
}
case reflect.Map:
var raw map[string]any
if err := rt.ExportTo(values, &raw); err != nil {
return nil, fmt.Errorf("options: expected object, got %T", values)
}
opt, err := extractSelectOptionFromMap(raw)
if err != nil {
return nil, err
}
opts = append(opts, opt)
case reflect.TypeFor[*common.ElementHandle]().Kind():
opts = append(opts, t.(*common.ElementHandle)) //nolint:forcetypeassert
case reflect.TypeFor[sobek.Object]().Kind():
obj := values.ToObject(rt)View on GitHub (pinned to 8d06114777)