Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Use the mods API changedplugins/mods/api

Nearest release: v2.1.304, published 6 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 20 Oct 2026 02:35 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 20 Oct 2026 02:37 UTC.

Upstream edited
Recorded here
Lines+83added
Lines−0removed
From line 218 where the diff opens
First seen 1 Oct 2026 this site's first read of the page
Recorded edits12to this page, all time

### Calls and background work after the user interrupts a turn #### Retry a refused or dropped call #### What refused calls return #### Work your mod started before the interruption

The whole hunk

from line 218, old and new numbered
/
lines
from line 218
218218 
219219Timers stop when the module reloads. For long-running work inside a hook, [`next.signal`](/docs/en/plugins/mods/reference#the-hook-function) is an `AbortSignal` that aborts when the event your hook is handling is abandoned, for example when the user interrupts, so pass it to anything long-running.
220220 
221### Calls and background work after the user interrupts a turn
222 
223The reason `the session was stopped and nobody has sent input since` in a result or error means the user stopped a running turn, such as with Esc or **Stop**. After that interruption, calls that start new work in the session are refused until the user's next input, such as a message at the prompt.
224 
225Apart from `$.prompt.submit` and `$.command.run`, this handling of calls and background work after an interruption requires Claude Code v2.1.304 or later.
226 
227#### Retry a refused or dropped call
228 
229Make a refused or dropped call again from a [`turn.complete`](/docs/en/plugins/mods/events#follow-a-turn) hook. Calls stay refused until the user's next input, and nothing queues or repeats them for you.
230 
231When a call's result or error contains one of these strings, keep its arguments for a later retry:
232 
233* **`the session was stopped and nobody has sent input since`**: the call was refused
234* **`was removed from the queue before it ran`**: the prompt or command left the queue without running and was dropped, for example when the user stopped the turn
235 
236In this example, call `submitPrompt` from your background job in place of [`$.prompt.submit`](#start-a-turn-from-a-background-job). When the result or the error carries one of those strings, `submitPrompt` keeps the text in `pendingText` for the `turn.complete` hook to submit again:
237 
238```javascript theme={null}
239// The text of the last refused or dropped prompt, or null
240let pendingText = null
241 
242async function submitPrompt($, text) {
243 let reason
244 try {
245 const result = await $.prompt.submit({ text })
246 reason = result?.drop ?? ''
247 } catch (error) {
248 reason = String(error?.message ?? error)
249 }
250 if (reason.includes('the session was stopped and nobody has sent input since') ||
251 reason.includes('was removed from the queue before it ran')) {
252 pendingText = text
253 }
254 // Any other result or error isn't retried
255}
256 
257on('turn.complete', async ($, e, next) => {
258 if (pendingText !== null) {
259 const text = pendingText
260 // Empty pendingText before retrying, so that a second run of this hook
261 // doesn't submit the same text.
262 pendingText = null
263 // Not awaited: the hook would stay open until the new turn starts
264 submitPrompt($, text)
265 }
266 return next(e)
267})
268```
269 
270Before the user's next input, `turn.complete` can fire for the interrupted turn itself and for a subagent's turn, and calls made then are refused again. In that case `submitPrompt` keeps the text for a later `turn.complete`.
271 
272For a call that rejects, such as `$.command.run`, catch the error and test its message the way `submitPrompt` tests `reason`.
273 
274#### What refused calls return
275 
276In the results, `<reason>` stands for `the session was stopped and nobody has sent input since`:
277 
278| Some refused calls | Result until the user's next input |
279| :- | :- |
280| `$.prompt.submit` | Resolves with `{ drop: '<reason>' }` and queues no prompt |
281| `$.command.run` | Rejects with an error whose message ends with `<reason>` |
282| [`$.agent.spawn`](/docs/en/plugins/mods/reference#mods-api-methods) | Resolves with `{ deny: '<reason>' }` and starts no subagent |
283| `$.session.send` to a subagent that finished | Resolves with `{ isDelivered: false, reason: 'Agent "<id>" was not resumed: <reason>.' }`, where `<id>` is the subagent's id. A subagent that's still running receives the message. |
284| `$.session.send` to an [agent team](/docs/en/agent-teams) teammate | Resolves with `{ isDelivered: false, reason: 'Teammate "<name>" was not messaged: <reason>.' }`, where `<name>` is the teammate's name |
285| [`$.tool.call`](/docs/en/plugins/mods/reference#mods-api-methods) of Bash with `run_in_background: true`, Monitor, or CronCreate | Resolves with `{ deny: '<tool> was not run: it starts background work, a schedule or a goal, and <reason>' }`, where `<tool>` is the tool's name |
286 
287Along with these `$.session.send` and `$.tool.call` results, the user can see the [`Stopped:` toast](/docs/en/plugins/mods/troubleshoot#stopped-type-a-message-to-continue).
288 
289#### Work your mod started before the interruption
290 
291After the user stops a running turn, for example with Esc, some work your mod had already started is dropped and some waits for the user's next input.
292 
293| Work | What happens until the user's next input | What to do |
294| :- | :- | :- |
295| A prompt from `$.prompt.submit` still in the queue | Dropped. The call resolves with `{ drop: 'the prompt was removed from the queue before it ran' }`. | Submit it again as [Retry a refused or dropped call](#retry-a-refused-or-dropped-call) shows |
296| A command from `$.command.run` still in the queue | Dropped. The call rejects with an error whose message includes `the command was removed from the queue before it ran`. | Run it again as [Retry a refused or dropped call](#retry-a-refused-or-dropped-call) shows |
297| A one-time job scheduled with a tool such as CronCreate that comes due before the user's next input | Starts no turn then, and runs after that input | Nothing needed |
298| A recurring job scheduled with a tool such as CronCreate that comes due before the user's next input | Starts no turn then. The job loses that run and keeps its schedule. | Nothing needed |
299| An event from a monitor your mod started | The monitor keeps running. An event the monitor raises before the user's next input is dropped, except the notice that the monitor ended, which arrives after that input. | Nothing can be done |
300| A subagent your mod spawned and later resumed with `$.session.send` that finishes before the user's next input | Its finish notice waits, and reaches the conversation after that input | Nothing needed |
301 
302When a scheduled job comes due or a monitor raises an event before the user's next input, the user can see the [`Stopped:` toast](/docs/en/plugins/mods/troubleshoot#stopped-type-a-message-to-continue).
303 
221304## Send and receive messages between sessions
222305 
223306A mod can send a plain-text message to another of your sessions, to one of this session's subagents, or to a teammate in its [agent team](/docs/en/agent-teams). It can also observe the messages that arrive and leave.
Feedback