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

  1. 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
  2. Fix casing/typos in the action producer (LLM prompt, planner, or mapping table) so it emits only supported verbs
  3. 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

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


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)