| … | … | @@ -4608,10 +4611,70 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | |
| 4633 | + | Effect.as(true), | |
| 4634 | + | Effect.catch(() => Effect.succeed(false)), | |
| 4635 | + | ); | |
| 4636 | + | if (!stopAcknowledged || !context.liveTaskIds.delete(taskId)) { | |
🟠 High Layers/ClaudeAdapter.ts:4636
A delayed concurrent interruptTurn can interrupt a newer turn after the original turn has already been stopped. The second call reaches context.query.interrupt() after its stopTask result is discarded, and _turnId is ignored; capture and re-check the requested turn identity before interrupting.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4636: |
| 2 | |
| 3 | A delayed concurrent `interruptTurn` can interrupt a newer turn after the original turn has already been stopped. The second call reaches `context.query.interrupt()` after its `stopTask` result is discarded, and `_turnId` is ignored; capture and re-check the requested turn identity before interrupting. |
| … | … | @@ -4608,10 +4611,70 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | |
| 4670 | + | yield* Effect.tryPromise({ | |
| 4671 | + | try: () => context.query.interrupt(), | |
| 4672 | + | catch: (cause) => toRequestError(threadId, "turn/interrupt", cause), | |
| 4673 | + | }); | |
🟠 High Layers/ClaudeAdapter.ts:4673
A subagent that starts during query.interrupt() is left running, and the Claude CLI stays alive instead of taking the stopSessionInternal() fallback. The liveTaskIds check occurs only before the interrupt, so recheck it after query.interrupt() and close the session if a task was added.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4673: |
| 2 | |
| 3 | A subagent that starts during `query.interrupt()` is left running, and the Claude CLI stays alive instead of taking the `stopSessionInternal()` fallback. The `liveTaskIds` check occurs only before the interrupt, so recheck it after `query.interrupt()` and close the session if a task was added. |