Cancel Monitor
Action type: actions/monitors/cancel.
Use this action to disarm an armed monitor the agent no longer needs — the "actually, forget it" flow. The monitor moves to expired without firing: its wake is never posted, and its armed-cap slot frees immediately instead of waiting for the TTL.
There is no re-arm. To change what a monitor watches, cancel it and create a new one with Create Monitor.
Fields
| Field | What it does |
|---|---|
| monitorId | CEL resolving to the _id of the armed monitor — the monitorId a Create Monitor step returned (e.g. step(0).monitorId), or one read from the read-only monitors data type |
| conversationId | The conversation the monitor wakes. Defaults to the conversation the run is in — a workflow run has no conversation, so workflow steps must set it. It must match the monitor's own |
What later steps can use
step(N).monitorId— the canceled monitor's idstep(N).monitorState—expiredafter a successful cancel
(As with Create Monitor, read the result via these outputs, not step(N).status — status is reserved for HTTP status codes.)
Scope: your conversation's monitors only
A cancel is refused unless the monitor belongs to your account and wakes the conversation the cancel is scoped to. To cancel a monitor wired to a different conversation, pass that conversation's id explicitly. The account is the hard boundary here; the conversation check protects against mistakes (disarming another conversation's watch by accident), not against a caller that deliberately names the right conversation.
When the cancel is refused
| Error | Meaning |
|---|---|
monitor_invalid_id | monitorId is not a valid monitor id |
monitor_missing_conversation | No conversation to scope the cancel to — workflow runs must pass one |
monitor_not_found | No monitor with that id on this account |
monitor_not_in_conversation | The monitor wakes a different conversation — pass its conversationId |
monitor_not_armed | Already fired, expired or error — nothing to cancel. If it fired, the wake message is already in the conversation |
monitor_being_evaluated | The sweeper is evaluating the monitor at this instant — retry shortly (an evaluation lease lasts at most 2 minutes; 3 for agent_tool watches) |
Races, honestly
A monitor that fires while you cancel stays fired — the cancel answers monitor_not_armed, and the wake is already in the conversation. A monitor mid-evaluation refuses the cancel (monitor_being_evaluated) rather than racing it — the sweeper re-confirms its claim at the last instant before sending, so canceling never un-posts a wake and a canceled monitor never fires afterwards. One narrow residual is worth knowing: if a worker crashes after delivering a wake but before recording the fire, the row briefly reads as armed again and a cancel can win it — you would then hold a delivered wake for a monitor that reads as canceled. That takes a crash at exactly the wrong instant, and the wake itself is deduplicated regardless.