Skip to main content
Every action Reticle can perform takes the same shape: a ref from reticle_snapshot or reticle_query, an action name, and an optional args object. The same seventeen actions are available on reticle_act, which proves nothing, and on reticle_act_and_wait, which returns a verdict.

Arguments that are not actions

Three args keys apply across actions rather than belonging to one:
confirmDangerous and holdMs are routinely confused because both show up around delete buttons. holdMs is how long the button is held; confirmDangerous is permission to press it at all. Passing the wrong one gets you either a refusal or a press that was never held.

The refusal you will meet first

Reticle blocks a control that looks destructive before acting on it:
A stale ref is refused the same way, with "ref 'e303' no longer resolves to an element" and a recovery note telling you to re-query. Both refusals cost a turn and prevent a false green, which is the trade.

fill versus type

fill replaces. type appends. Reaching for type when you meant fill is how a field ends up containing hellohello, and neither call will complain.

press takes text, not key

Both are accepted today, and text wins when both are present. Use text. It is what the tool description documents.
This one has history worth knowing. The implementation used to read args.key and default to Enter, so the documented call, { action: "press", args: { text: "Escape" } }, silently sent Enter and reported success.Three consequences, worst last: the requested key never arrived, so Escape-to-close and Tab-traversal went unverified while looking verified; nothing in the result said the argument had been ignored; and Enter is not a neutral substitute. On a focused field inside a form it submits it. A request to close a dialog could file the form behind it.Two field reports were exactly this, both diagnosed as “synthetic events don’t reach the app”. Wrong root cause: the event reached the app perfectly well and simply said Enter.
That bug is fixed, and the reason it is written down here is that it is the exact shape of failure Reticle exists to catch. An action that reports success while doing something else.

Batching

Several actions in one round trip:
reticle_act_sequence returns ok: true when the steps were dispatched, not when they worked. Batch the setup, then prove the outcome with reticle_act_and_wait on the final step.

Real versus synthetic input

inputMode in the response says which you got. synthetic means events dispatched programmatically. Correct for the overwhelming majority of apps. real means native CDP input, available under reticle drive, and needed by a few drag-and-drop and pointer-gesture libraries.
On a throttled tab, synthetic timers and pointer gestures can silently no-op. Pass refuseWhenThrottled: true to fail loudly instead of acting into a tab the browser has paused.

What every action reports

dispatched, targetMatched, visible, enabled, valueChanged, focusMoved, domMutatedWithin, defaultPrevented, occluded, occludedBy and scrolledIntoView. Plus the element’s testid, component, role, name and source file and line. Fields sitting at their uninformative default are omitted, so a clean action collapses to its consequence. A missing visible means true, not false. Read an absence as “nothing to report” rather than as a failure. occluded is the answer to a large share of “the button doesn’t work” reports: the click landed on the modal overlay sitting on top of it.

Full field-by-field walkthrough

What each effect field tells you, with a real response.
Last modified on September 18, 2026