{"record":{"id":"36e7a4db96595e5d","repo":"grafana/k6","slug":"dispatching-locator-event-q-to-q-w","errorCode":null,"errorMessage":"dispatching locator event %q to %q: %w","messagePattern":"dispatching locator event %q to %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/locator.go","lineNumber":638,"sourceCode":"\t\treturn fmt.Errorf(\"tapping on %q: %w\", l.selector, err)\n\t}\n\n\tapplySlowMo(l.ctx)\n\n\treturn nil\n}\n\n// DispatchEvent dispatches an event for the element matching the\n// locator's selector with strict mode on.\nfunc (l *Locator) DispatchEvent(typ string, eventInit any, opts *FrameDispatchEventOptions) error {\n\tl.log.Debugf(\n\t\t\"Locator:DispatchEvent\", \"fid:%s furl:%q sel:%q typ:%q eventInit:%+v opts:%+v\",\n\t\tl.frame.ID(), l.frame.URL(), l.selector, typ, eventInit, opts,\n\t)\n\n\topts.Strict = true\n\tif err := l.frame.dispatchEvent(l.selector, typ, eventInit, opts); err != nil {\n\t\treturn fmt.Errorf(\"dispatching locator event %q to %q: %w\", typ, l.selector, err)\n\t}\n\n\tapplySlowMo(l.ctx)\n\n\treturn nil\n}\n\n// WaitFor waits for the element matching the locator's selector with strict mode on.\nfunc (l *Locator) WaitFor(opts *FrameWaitForSelectorOptions) error {\n\tl.log.Debugf(\"Locator:WaitFor\", \"fid:%s furl:%q sel:%q opts:%+v\", l.frame.ID(), l.frame.URL(), l.selector, opts)\n\n\topts.Strict = true\n\t_, err := l.frame.waitFor(l.selector, opts, 20)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"waiting for %q: %w\", l.selector, err)\n\t}\n\n\treturn nil","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/locator.go#L620-L656","documentation":"Thrown by Locator.DispatchEvent() when the wrapped frame.dispatchEvent call fails. Strict mode is forced on, so the selector must resolve to exactly one element. Typical failures: strict-mode violation, timeout waiting for the element, or the element's execution context being destroyed (navigation) while the event was dispatched.","triggerScenarios":"locator.dispatchEvent(type, eventInit) where the selector matches 0 or >1 elements; the page navigates between resolving the element and dispatching, destroying the context; the element is detached from the DOM past the timeout.","commonSituations":"Dispatching 'click' or 'input' events to trigger SPA handlers on elements rendered late; selectors matching both a parent and child; dispatching during a client-side route transition that re-renders the tree.","solutions":["Use a unique selector that matches exactly one element","await locator.waitFor() before dispatching","Re-dispatch after navigation/SPA transitions complete (element handles do not survive re-render)","Increase opts.timeout on slow pages"],"exampleFix":"// before\nawait page.locator('.item').dispatchEvent('click'); // matches many items\n\n// after\nawait page.locator('.item[data-id=\"42\"]').waitFor();\nawait page.locator('.item[data-id=\"42\"]').dispatchEvent('click');","handlingStrategy":"try-catch","validationCode":"const els = await page.$$(sel);\nif (els.length !== 1) throw new Error(`selector matches ${els.length} elements`);\nawait page.locator(sel).dispatchEvent('click');","typeGuard":"async function isAttached(page, sel) {\n  const el = await page.$(sel);\n  return el !== null;\n}","tryCatchPattern":"try {\n  await page.locator(sel).dispatchEvent('click', { bubbles: true });\n} catch (e) {\n  if (/timeout|strict mode/i.test(e.message)) {\n    await page.locator(sel).waitFor();\n    await page.locator(sel).dispatchEvent('click', { bubbles: true });\n  } else throw e;\n}","preventionTips":["Use unique selectors before dispatching synthetic events","Prefer locator.click() over dispatchEvent('click') when possible — it retries","Re-query locators after SPA route changes; never cache handles across renders"],"tags":["browser","locator","events","strict-mode","dom"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}