{"record":{"id":"8a03f214453eec87","repo":"grafana/k6","slug":"parsing-check-options-w","errorCode":null,"errorMessage":"parsing check options: %w","messagePattern":"parsing check options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/element_handle_mapping.go","lineNumber":31,"sourceCode":"// mapElementHandle to the JS module.\nfunc mapElementHandle(vu moduleVU, eh *common.ElementHandle) mapping { //nolint:gocognit,funlen,cyclop\n\trt := vu.Runtime()\n\tmaps := mapping{\n\t\t\"boundingBox\": func() *sobek.Promise {\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\tbox, err := eh.BoundingBox()\n\t\t\t\t// We want to avoid errors when an element is not visible or detached and instead\n\t\t\t\t// opt to return a nil rectangle -- this matches Playwright's behaviour.\n\t\t\t\tif errors.Is(err, common.ErrElementNotVisible) || errors.Is(err, common.ErrElementNotAttachedToDOM) {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t\treturn box, err\n\t\t\t})\n\t\t},\n\t\t\"check\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts := common.NewElementHandleSetCheckedOptions(eh.DefaultTimeout())\n\t\t\tif err := popts.Parse(vu.Context(), opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing check options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.Check(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"click\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts := common.NewElementHandleClickOptions(eh.Timeout())\n\t\t\tif err := popts.Parse(vu.Context(), opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing element click options: %w\", err)\n\t\t\t}\n\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\terr := eh.Click(popts)\n\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"contentFrame\": func() *sobek.Promise {\n\t\t\treturn promise(vu, func() (any, error) {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/browser/element_handle_mapping.go#L13-L49","documentation":"Thrown synchronously by ElementHandle.check() when its options object fails to parse. check() reuses ElementHandleSetCheckedOptions (a base-pointer options set: force, noWaitAfter, timeout, trial, strict, position), and in common/element_handle_options.go the only Parse step that can return an error is exporting the 'position' key into a map[string]float64. Because mapElementHandle's mapping returns (nil, error) before the promise is created, this surfaces as a plain JS exception at call time, not as a promise rejection.","triggerScenarios":"Calling el.check({ position: 'center' }) (string instead of object), { position: [10, 10] } (array), { position: { x: '10', y: 20 } } (x is a string), or position set to a number/boolean. Any non-object position, or an object whose x/y cannot export to float64, makes rt.ExportTo fail and the error is wrapped as 'parsing check options'. Scalar options (timeout, force, strict, trial) are lenient coercions and never produce this error; unknown keys are silently ignored.","commonSituations":"Porting Playwright scripts where position is documented as {x, y} but the value is built from strings (e.g. values read from getAttribute or a config file), or where a CSS keyword like 'center' is passed instead of computed coordinates. Also hit when options objects are constructed dynamically and position is accidentally set to null-like sentinels or arrays.","solutions":["Pass position as an object with numeric x/y: el.check({ position: { x: 10, y: 20 } })","Omit position entirely to check the element at its default clickable center","Coerce computed coordinates with Number() and verify with Number.isFinite before building the options object","Wrap the call in try/catch (not .catch) since the error is thrown synchronously, before a promise exists"],"exampleFix":"// before\nawait el.check({ position: 'center' });\n\n// after\nawait el.check({}); // default center, or:\nconst box = await el.boundingBox();\nawait el.check({ position: { x: box.x + 5, y: box.y + 5 } });","handlingStrategy":"type-guard","validationCode":"const p = opts?.position;\nif (p !== undefined && (typeof p !== 'object' || Array.isArray(p) ||\n    !Number.isFinite(Number(p.x)) || !Number.isFinite(Number(p.y)))) {\n  throw new Error('check(): position must be { x: number, y: number }');\n}","typeGuard":"function isValidPosition(p) {\n  if (p === undefined || p === null) return true;\n  return typeof p === 'object' && !Array.isArray(p) &&\n    Number.isFinite(Number(p.x)) && Number.isFinite(Number(p.y));\n}\nfunction isCheckOpts(o) {\n  return o == null || isValidPosition(o.position); // force/noWaitAfter/timeout/strict/trial coerce safely\n}","tryCatchPattern":"try {\n  await el.check(opts);\n} catch (e) {\n  if (/parsing check options/.test(String(e.message))) {\n    console.log(`bad check options: ${e.message}`); // fix position shape and retry\n  } else throw e;\n}","preventionTips":["Build position from boundingBox() numbers only; never pass CSS keywords like 'center'","Centralize pointer-action options construction in one helper so every action validates the same shape","Remember these parse errors throw synchronously: use try/catch, never .catch()"],"tags":["k6","browser","element-handle","check","option-parsing"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}