JuliusBrussee/caveman · error
option not found
Error message
option not found
What it means
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.
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.
Example fix
// before
Act(ctx, Action{Kind: "select", Text: "United States"})
// after
Act(ctx, Action{Kind: "select", Text: "US"}) // exact option value/label from the DOM Defensive patterns
Strategy: validation
Validate before calling
const ok = await page.evaluate((sel, wanted) => {
const el = document.querySelector(sel);
if (!el || el.tagName !== 'SELECT') return false;
return Array.from(el.options).some(o => o.value === wanted || o.label === wanted || o.textContent.trim() === wanted);
}, selector, option);
if (!ok) throw new Error(`option '${option}' not present in ${selector}`); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- resolve node returned no object
- browser function returned no result object
- browser function threw
- element not actionable: last box=%+v
- missing backend DOM node id
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/168a2559bd719ab0.
Report an issue: GitHub.
Appendix: source
Thrown at browse/cdp.go:207
})); err != nil {
return ActionResult{OK: false, Settled: false}, err
}
return dispatchedAction(), nil
case "select":
if err := d.scrollIntoView(runCtx, target); err != nil {
return ActionResult{OK: false, Settled: false}, err
}
if _, _, err := d.waitActionable(runCtx, target); err != nil {
return ActionResult{OK: false, Settled: false}, err
}
option := req.Option
if option == "" {
option = req.Text
}
if option == "" {
return ActionResult{OK: false, Settled: false}, errors.New("select: missing option")
}
if 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 {
return ActionResult{OK: false, Settled: false}, err
}
return dispatchedAction(), nil
case "scroll":
if err := d.scrollIntoView(runCtx, target); err != nil {
return ActionResult{OK: false, Settled: false}, err
}
if _, _, err := d.waitActionable(runCtx, target); err != nil {
return ActionResult{OK: false, Settled: false}, err
}
return dispatchedAction(), nil
default:
return ActionResult{OK: false, Settled: false}, fmt.Errorf("unknown action: %s", req.Action)
}
}
func dispatchedAction() ActionResult {
// CDP acknowledged dispatch, but asynchronous application state may still beView on GitHub (pinned to 3ee70a1026)