JuliusBrussee/caveman · error
unknown action
Error message
unknown action: %s
What it means
CDPDriver.Act dispatches a browser interaction (click, fill, etc.) keyed by req.Action. Any action name outside the switch's known cases is rejected with 'unknown action: %s', returning an unsuccessful ActionResult rather than guessing.
Solutions
- Print/log req.Action and compare it against the supported cases in Act's switch (browse/cdp.go) and use an exact supported action name
- Fix casing/typos in the action producer (LLM prompt, planner, or mapping table) so it emits only supported verbs
- If the action is legitimately new, implement its case in Act rather than reusing the string ad hoc
Example fix
// before
req := browse.ActionRequest{Action: "Click", ...} // wrong casing
// after
req := browse.ActionRequest{Action: "click", ...} // matches a case in Act's switch Defensive patterns
Strategy: validation
Validate before calling
var supportedActions = map[string]bool{"click": true, "fill": true /* see Act's switch */}
if !supportedActions[action] {
return fmt.Errorf("unsupported action %q for cdp driver", action)
} Prevention
- Define the action vocabulary as a shared typed enum/constants used by both planner and driver
- Constrain LLM/planner output with a schema that only allows known action names
- Add a unit test asserting every planner-emitted action is accepted by each driver backend
When it happens
Trigger: Calling Act with an ActionResult request whose Action string is not one of the driver's supported verbs — e.g. a typo ('clik'), a casing mismatch ('Click'), or an action supported by another driver backend but not the CDP driver.
Common situations: Agent-generated action plans containing hallucinated or unsupported action names; a driver abstraction shared across backends where one backend supports actions the CDP driver does not; schema drift after the action vocabulary changed upstream.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- element not actionable: last box=%+v
- start browser
- browser function returned no result object
- browser function threw
- option not found
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/0750cd03b5fa7d0f.
Report an issue: GitHub.
Appendix: source
Thrown at browse/cdp.go:220
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 be
// changing. Claiming settled=true here made agents trust an unverified result.
// A focused browser_snapshot is the cheap, evidence-bearing verification step.
return ActionResult{OK: true, Settled: false, Note: "dispatched; resnapshot to verify"}
}
func (d *CDPDriver) scrollIntoView(ctx context.Context, target Target) error {
return d.callOnNode(ctx, target, `function(){ this.scrollIntoView({block:"center", inline:"center", behavior:"instant"}); return true; }`)
}
// Shutdown closes the attached browser process. Ordinary Close only releases
// this driver context; direct CLI mode deliberately leaves its detached Chrome
// alive between snapshot and act commands until `browse close` calls Shutdown.
func (d *CDPDriver) Shutdown(ctx context.Context) error {View on GitHub (pinned to 3ee70a1026)