{"record":{"id":"a864cafc81a01ae1","repo":"grafana/k6","slug":"parsing-waitforselector-q-options-w","errorCode":null,"errorMessage":"parsing waitForSelector %q options: %w","messagePattern":"parsing waitForSelector %q options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/element_handle_mapping.go","lineNumber":301,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"parsing uncheck options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.Uncheck(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"waitForElementState\": func(state string, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseElementHandleWaitForElementStateOptions(rt, opts, eh.DefaultTimeout())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing waitForElementState options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, eh.WaitForElementState(state, popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"waitForSelector\": func(selector string, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseFrameWaitForSelectorOptions(rt, opts, eh.DefaultTimeout())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing waitForSelector %q options: %w\", selector, err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\teh, err := eh.WaitForSelector(selector, popts)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t\t}\n\t\t\t\treturn mapElementHandle(vu, eh), nil\n\t\t\t}), nil\n\t\t},\n\t}\n\tmaps[\"$\"] = func(selector string) *sobek.Promise {\n\t\treturn promise(vu, func() (any, error) {\n\t\t\teh, err := eh.Query(selector, common.StrictModeOff)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t}\n\t\t\t// ElementHandle can be null when the selector does not match any elements.\n\t\t\t// We do not want to map nil elementHandles since the expectation is a","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/browser/element_handle_mapping.go#L283-L319","documentation":"Thrown when ElementHandle.waitForSelector cannot parse its options. FrameWaitForSelectorOptions.Parse validates the state key against exactly four allowed values — attached, detached, visible, hidden — and returns '%q is not a valid DOM state' for anything else; timeout/strict are coerced and unknown keys ignored. Playwright-only states like enabled, disabled, stable or editable are therefore rejected here.","triggerScenarios":"waitForSelector('#el', {state: 'enabled'}), {state: 'stable'} or a typo like {state: 'visable'} — any state string outside attached|detached|visible|hidden.","commonSituations":"Copying Playwright examples that use state: 'enabled'/'disabled'; assuming the full Playwright state enum exists in the k6 browser module.","solutions":["Use one of the supported states: attached, detached, visible or hidden","To wait for enabled/disabled semantics, waitForSelector with state 'visible' plus an evaluate()-based predicate","Check the error text — it quotes the exact rejected state string"],"exampleFix":"// before\nawait handle.waitForSelector('#submit', { state: 'enabled' });\n// after\nawait handle.waitForSelector('#submit', { state: 'visible' });","handlingStrategy":"validation","validationCode":"const DOM_STATES = ['attached', 'detached', 'visible', 'hidden'];\nif (opts?.state !== undefined && !DOM_STATES.includes(opts.state)) {\n  throw new Error(`invalid state '${opts.state}'; allowed: ${DOM_STATES.join(', ')}`);\n}\nawait handle.waitForSelector(selector, opts);","typeGuard":"function isDOMElementState(v) {\n  return ['attached', 'detached', 'visible', 'hidden'].includes(v);\n}","tryCatchPattern":"try {\n  await handle.waitForSelector(sel, opts);\n} catch (e) {\n  if (String(e).includes('parsing waitForSelector') && String(e).includes('not a valid DOM state')) {\n    await handle.waitForSelector(sel, { ...opts, state: 'visible' });\n  } else { throw e; }\n}","preventionTips":["Whitelist the four supported states in a shared constant","Do not assume Playwright's enabled/disabled/stable states exist in k6","Test waitForSelector option handling early in script development to catch enum mismatches cheaply"],"tags":["k6","browser","element-handle","waitforselector","state","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-09-14T20:10:14.619Z","contentChangedAt":"2026-09-14T20:10:14.619Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}