{"record":{"id":"168a2559bd719ab0","repo":"JuliusBrussee/caveman","slug":"option-not-found","errorCode":null,"errorMessage":"option not found","messagePattern":"option not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"browse/cdp.go","lineNumber":207,"sourceCode":"\t\t})); err != nil {\n\t\t\treturn ActionResult{OK: false, Settled: false}, err\n\t\t}\n\t\treturn dispatchedAction(), nil\n\tcase \"select\":\n\t\tif err := d.scrollIntoView(runCtx, target); err != nil {\n\t\t\treturn ActionResult{OK: false, Settled: false}, err\n\t\t}\n\t\tif _, _, err := d.waitActionable(runCtx, target); err != nil {\n\t\t\treturn ActionResult{OK: false, Settled: false}, err\n\t\t}\n\t\toption := req.Option\n\t\tif option == \"\" {\n\t\t\toption = req.Text\n\t\t}\n\t\tif option == \"\" {\n\t\t\treturn ActionResult{OK: false, Settled: false}, errors.New(\"select: missing option\")\n\t\t}\n\t\tif err := d.callOnNode(runCtx, target, fmt.Sprintf(`function(){ const wanted = %s; const options = Array.from(this.options || []); const match = options.find(o => o.value === wanted || o.label === wanted || o.textContent.trim() === wanted); if (!match) { throw new Error(\"option not found\"); } this.value = match.value; this.dispatchEvent(new Event(\"input\", {bubbles:true})); this.dispatchEvent(new Event(\"change\", {bubbles:true})); return true; }`, jsString(option))); err != nil {\n\t\t\treturn ActionResult{OK: false, Settled: false}, err\n\t\t}\n\t\treturn dispatchedAction(), nil\n\tcase \"scroll\":\n\t\tif err := d.scrollIntoView(runCtx, target); err != nil {\n\t\t\treturn ActionResult{OK: false, Settled: false}, err\n\t\t}\n\t\tif _, _, err := d.waitActionable(runCtx, target); err != nil {\n\t\t\treturn ActionResult{OK: false, Settled: false}, err\n\t\t}\n\t\treturn dispatchedAction(), nil\n\tdefault:\n\t\treturn ActionResult{OK: false, Settled: false}, fmt.Errorf(\"unknown action: %s\", req.Action)\n\t}\n}\n\nfunc dispatchedAction() ActionResult {\n\t// CDP acknowledged dispatch, but asynchronous application state may still be","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/browse/cdp.go#L189-L225","documentation":"During the browser `select` action, Act evaluates a JS function over the target <select> element that finds the first option whose value, label, or trimmed text equals the requested option string. If no option matches, the injected function throws \"option not found\", which the Go driver surfaces as the action error. It exists to fail loudly instead of silently setting a value that does not correspond to any real option.","triggerScenarios":"Calling Act with a select action whose option (or fallback req.Text) does not exactly match any option's value, label, or textContent on the target <select> element. The comparison is exact string equality — case, whitespace, and leading/trailing spaces matter.","commonSituations":"Passing a human-readable label ('United States') when the option value is a code ('US') and the label text differs slightly; copying option text that contains hidden whitespace or non-breaking spaces; the page re-rendering the select after load so options differ from what the caller assumed; targeting the wrong element so `this.options` is empty.","solutions":["Inspect the target select's options (value and text) and pass an exact match — try the option's `value` attribute first.","Trim/normalize the option string (case, whitespace) to match the DOM text exactly.","Verify Act resolved the intended target element; a wrong selector yields a select with no matching options.","If the select is populated asynchronously, wait for the options to render before issuing the select action."],"exampleFix":"// before\nAct(ctx, Action{Kind: \"select\", Text: \"United States\"})\n// after\nAct(ctx, Action{Kind: \"select\", Text: \"US\"}) // exact option value/label from the DOM","handlingStrategy":"validation","validationCode":"const ok = await page.evaluate((sel, wanted) => {\n  const el = document.querySelector(sel);\n  if (!el || el.tagName !== 'SELECT') return false;\n  return Array.from(el.options).some(o => o.value === wanted || o.label === wanted || o.textContent.trim() === wanted);\n}, selector, option);\nif (!ok) throw new Error(`option '${option}' not present in ${selector}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the option's `value` attribute, read from the DOM, not a hand-typed label.","Normalize whitespace/case of option text before matching.","Wait for dynamic selects to populate before selecting.","Verify the target selector points at the actual <select> element."],"tags":["browser","dom","select","cdp"],"backgroundTag":"element-not-found","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}