Stopping an AI agent should prevent new work and account for work already in progress. A stopped chat stream does not establish that a worker, export or remote job stopped too. The application needs a cancellation path and a final status report that distinguishes requested cancellation, confirmed termination and work that had already completed.
This is different from rollback. Rollback concerns reversing changes; cancellation concerns preventing further execution. A published message can remain published after the agent stops. A completed file can remain available. The product should tell the user what stopped, what finished and what still needs reconciliation.
- 01A stop request is not a completion receipt.Wait for the relevant worker or service to report its final state.
- 02Account for children and remote jobs.Work can outlive the conversation that launched it.
- 03Preserve the distinction from rollback.Stopping future execution does not reverse completed side effects.
- 04Stop scheduling before stopping workers.Prevent new launches first, then signal active children through their supported mechanisms and keep enough control state alive to collect their answers.
01 — StatesUse states that describe what happened
A cancellation interface needs more than a single stopped flag. The proposed states below help the user decide whether to wait, inspect results or take a separate recovery action. They are application design guidance rather than protocol-defined status names.
| State | Meaning | Next step |
|---|---|---|
| Stop requested | The application accepted the user’s request | Prevent new launches and contact active work |
| Cancellation pending | A worker or service has not confirmed its outcome | Continue bounded reconciliation |
| Cancelled | The relevant work confirmed termination | Report any completed partial results |
| Completed before cancellation | The operation finished first | Show the result and any side effects |
| Cancellation unsupported | The service has no applicable stop operation | Track completion and prevent downstream actions |
| Outcome unknown | The system cannot yet establish final state | Keep the uncertainty visible; do not resubmit blindly |
02 — Cooperative stopsCancellation is often cooperative
Python’s asyncio task documentation distinguishes requesting cancellation from a task actually being cancelled. The coroutine can perform cleanup and may suppress the cancellation exception, so calling the request method does not by itself prove termination. This is one concrete implementation example, not a claim that every agent runtime uses Python.
The MCP Ruby SDK’s server cancellation documentation likewise describes cooperative handling rather than forcibly terminating tool code. The lesson for application design is to inspect the contract of each execution layer. A notification crossing one boundary does not establish that every downstream activity acknowledged it.
For the user, the language can stay simple: stopping, stopped, already completed or status unknown. The implementation should preserve enough detail to justify whichever label appears. Do not show stopped merely because the interface stopped receiving text.
After the user presses stop, verify that no new downstream action begins. Then account for every action that was already in progress. Test both parts; they fail in different ways.
03 — OwnershipGive every job an owner and a cancellation path
Track the work launched by a task: local workers, subprocesses, tool requests and remote job identifiers. If the application cannot enumerate its children, it cannot reliably explain what a stop request covered. Make ownership part of job creation rather than trying to reconstruct it from logs afterward.
When cancellation is requested, stop scheduling new work first. Signal the active children through their supported mechanisms. Keep enough control state alive to collect acknowledgments and reconcile outcomes. Terminating the parent process immediately can remove the only component that knows what remains active.
Remote work needs its own treatment. A service may offer cancellation, may finish before the request arrives, or may have no stop operation. In the last case, prevent the result from triggering publication or another action after the user has cancelled the task. The underlying computation and the downstream business action are separate boundaries.
A pending retry also counts as future work. Remove or invalidate it under the task’s cancellation state so a delayed message cannot restart the workflow. Check that a worker loading an old checkpoint observes the current task status before acting.
04 — The raceHandle the operation that finishes during the stop
Consider an illustrative export. The user presses stop while the remote service is writing the file. If the export completes first, deleting the local progress indicator does not undo the file. Read the final job status and report that it completed before cancellation. Whether to retain or remove the file is a separate decision.
For a write with an uncertain response, query the authoritative state before trying again. A repeated action could duplicate a delivery or create a second artifact. The stop path should use the same stable operation identifiers as the normal recovery path.
Our long-running tool-call analysis addresses waiting and polling. Rollback and checkpoint patterns cover recovery after changes. This article concerns the boundary between a user’s stop request and work that can still execute.
05 — TestingTest cancellation where the workflow can branch
Use a controlled fixture that can pause before launch, during tool execution, after a side effect and before final reporting. Request cancellation at each point. Verify the user-facing state, the worker state and the absence of unauthorized downstream actions. A test that only stops text generation misses the behavior that matters.
Include a child that is slow to acknowledge and a service that reports completion after cancellation was requested. The application should remain honest in both cases. It should not hang indefinitely, and it should not claim a confirmed stop when its reconciliation budget expires.
Make cleanup bounded and specific. Release temporary resources your task owns, preserve useful diagnostic status and avoid broad cleanup that could remove unrelated work. The policy should distinguish disposable scratch data from completed deliverables the user may still need.
For a wider reliability review, our agent observability checklist helps identify what evidence the system records. Add cancellation states to that evidence so support can explain the outcome without guessing from the last chat message.
06 — The failuresFour stop buttons that did not stop the work
A stop button that only stops the visible stream is the common failure, and it fails in several ways. The illustrative cases below each follow from skipping one section of this guide. They are patterns the state table describes, not observed incidents.
The stopped stream
The chat stops producing text and the interface shows stopped. A worker is still writing the export it was asked for. The label came from the interface losing its stream, not from any worker confirming termination.
The orphaned parent
The application terminates the parent process immediately on stop. The children it launched keep running, and the only component that knew what remained active is gone. Nobody can say what the stop covered.
The delayed retry
The task is cancelled and reported stopped. A retry queued before the stop fires a minute later and restarts the workflow from an old checkpoint that never checked the current task status.
The export marked cancelled
The user presses stop while a remote service is writing a file. The service finishes first. The application deletes its progress indicator and reports cancelled; the file exists and nobody was told.
Each failure produces a confident final status that the evidence does not support. The report in the next section is where the status has to earn its wording.
07 — The recordThe final status report in five lines
The conclusion asks for a final status the user can decide from, and five lines are enough to carry it. What was cancelled: the work that confirmed termination through its own contract, named by job. What completed first: the operations that finished before the stop reached them, with their results and where they live. Which side effects remain: a published message, a saved file, a created record, each of which cancellation does not reverse and rollback may. What could not be confirmed: the remote job with no stop operation, the child that did not acknowledge within the reconciliation budget, reported as status unknown rather than folded into stopped. And the next action: wait, inspect or recover, with the identifiers the user needs to do it.
An illustrative report for a stopped research-and-export task reads: cancelled, the two remaining web lookups, confirmed by the worker; completed first, the summary document, saved at its location; side effects remaining, none published; could not be confirmed, the spreadsheet export job at the remote service, which offers no cancellation and had not reported a final state when the reconciliation budget ended, with its job identifier; next action, check the job status before deciding whether to keep or delete the file. That report lets the user act. A single word, stopped, would not.
The five lines are also the acceptance test the callout above describes, written out. After the stop, no new downstream action begins, which is what makes line one possible; every action already in progress is accounted for, which is lines one to four; and the user knows what to do, which is line five. The states in the table map onto the lines, so the application can fill the report from state rather than from the last chat message.
It means the application accepted the user’s instruction. Cancelled means the relevant work confirmed it stopped. Already completed and status unknown are honest answers too; stopped, on the strength of a stream ending, is the label the report should not carry.
08 — DecisionWhat to do next
Pick the workflow with the most background work and write its five-line report for a stop pressed mid-run. Any line that cannot be filled from the application’s own state is the gap the ownership section describes, and it is the first thing to build.
A stop button needs an accountable end state.
Define ownership, prevent new launches and reconcile active work. Preserve useful completed results and explain uncertain outcomes. The user should be able to decide what to do next from the final status, without having to infer whether the background work is still running.
For implementation support, explore our AI transformation services.