{"record":{"id":"23a1abdea018058f","repo":"grafana/k6","slug":"parsing-select-options-values-w","errorCode":null,"errorMessage":"parsing select options values: %w","messagePattern":"parsing select options values: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/element_handle_mapping.go","lineNumber":202,"sourceCode":"\n\t\t\t\tab := rt.NewArrayBuffer(bb)\n\n\t\t\t\treturn &ab, nil\n\t\t\t}), nil\n\t\t},\n\t\t\"scrollIntoViewIfNeeded\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts := common.NewElementHandleBaseOptions(eh.DefaultTimeout())\n\t\t\tif err := popts.Parse(vu.Context(), opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing scrollIntoViewIfNeeded options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.ScrollIntoViewIfNeeded(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"selectOption\": func(values sobek.Value, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tconvValues, err := ConvertSelectOptionValues(vu.Runtime(), values)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing select options values: %w\", err)\n\t\t\t}\n\t\t\tpopts := common.NewElementHandleBaseOptions(eh.DefaultTimeout())\n\t\t\tif err := popts.Parse(vu.Context(), opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing selectOption options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn eh.SelectOption(convValues, popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"selectText\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts := common.NewElementHandleBaseOptions(eh.DefaultTimeout())\n\t\t\tif err := popts.Parse(vu.Context(), opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing selectText options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.SelectText(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/browser/element_handle_mapping.go#L184-L220","documentation":"Thrown synchronously by ElementHandle.selectOption() when the values argument (not the trailing options object) cannot be converted. ConvertSelectOptionValues in browser/mapping.go accepts a string, an object with value/label/index, an array mixing both, or an ElementHandle; anything else errors with messages like 'options: expected string or object, got <type>', 'options[<key>]: expected string|int, got <type>', or 'options: unsupported type <type>'. This is one of the few parse errors in this mapping that fires routinely.","triggerScenarios":"el.selectOption([10]) (numbers in the array), el.selectOption(true) or el.selectOption(5) (non-string scalar), el.selectOption({ value: 42 }) (value not a string), el.selectOption({ index: '2' }) (index not an int), or an array containing null/booleans: each returns 'options: expected string or object, got ...' or a per-key message.","commonSituations":"Reading option values from JSON/CSV test data where numbers stay numbers ({ index: 2 } written as string '2', or value keys as IDs); porting Playwright tests that also accept these shapes and silently coerce; mixing label strings and numeric indices in one array built by a data-driven loop.","solutions":["Pass values as strings or { value: 'v' } / { label: 'l' } / { index: 3 } with string strings and integer index","Stringify data-driven values before calling: values.map(String) for value/label keys, parseInt for index","Validate the values array with a helper that enforces string-or-{value,label,index} before the call","Catch synchronously with try/catch; the throw happens before any promise is created"],"exampleFix":"// before\nawait el.selectOption([10, { value: 42 }, { index: '2' }]);\n\n// after\nawait el.selectOption(['10', { value: '42' }, { index: 2 }]);","handlingStrategy":"validation","validationCode":"function validateSelectValues(values) {\n  if (values == null) return values;\n  const list = Array.isArray(values) ? values : [values];\n  for (const v of list) {\n    if (typeof v === 'string') continue;\n    if (typeof v === 'object' && v !== null && !Array.isArray(v)) {\n      for (const [k, raw] of Object.entries(v)) {\n        if ((k === 'value' || k === 'label') && typeof raw !== 'string')\n          throw new Error(`selectOption(): options[${k}] must be a string`);\n        if (k === 'index' && !Number.isInteger(raw))\n          throw new Error('selectOption(): options[index] must be an integer');\n      }\n      continue;\n    }\n    throw new Error(`selectOption(): values must be string or {value,label,index}, got ${typeof v}`);\n  }\n  return values;\n}","typeGuard":"function isSelectOptionValue(v) {\n  if (typeof v === 'string') return true;\n  if (typeof v !== 'object' || v === null || Array.isArray(v)) return false;\n  return Object.entries(v).every(([k, raw]) =>\n    (k === 'value' || k === 'label') ? typeof raw === 'string'\n    : k === 'index' ? Number.isInteger(raw)\n    : false);\n}","tryCatchPattern":"try {\n  await el.selectOption(values, opts);\n} catch (e) {\n  if (/parsing select options values|options: expected|string or object|unsupported type|is not a valid/.test(String(e.message))) {\n    console.log(`fix selectOption values: ${e.message}`);\n  } else throw e;\n}","preventionTips":["Stringify data-driven values before passing: value/label must be strings, index must be an integer","Never put numbers, booleans, or null directly in the values array","An ElementHandle (option element) is also accepted as a value; strings match value OR label"],"tags":["k6","browser","element-handle","select-option","option-parsing"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}