Skip to content

[BUG] CancelTask fails after an ask-user answer resumed the task ("deferred continuation cannot be resumed") #3314

Open

Description

@yyewolf

Bug description

CancelTask fails on a task that was resumed by answering an ask-user question and is now working again:

-32603 failed to cancel: cancelation failed: restore runtime pending turn: deferred continuation cannot be resumed; start a new session

The task keeps running and there is no way to stop it short of deleting the whole session. That matters when the resumed work has side effects (here the agent went on to clone a repository and was heading towards git push).

deferred continuation cannot be resumed; start a new session is runtime.ErrSessionAbandoned (go/harness/runtime/runtime.go). It looks like cancellation tries to restore the deferred continuation, which has already been consumed by the answer, instead of cancelling the live turn the answer started.

Steps to reproduce

  1. A Claude harness agent calls AskUserQuestion and the task goes input-required.
  2. Answer it with a valid ask_user_response. The agent resumes and the task is TASK_STATE_WORKING.
  3. While it works, CancelTask the task.

Expected

The running turn is stopped and the task becomes TASK_STATE_CANCELED, as it does for a task that never paused.

Actual

The error above. The task stays TASK_STATE_WORKING and the agent keeps going. Deleting the session from the UI did stop it.

Environment

kagent v1.0.0-alpha17, Substrate v0.6.0-alpha3, Claude harness (Claude Code 2.1.285).

Activity

  1. astrogilda commented on Oct 26, 2026

    @astrogilda

    @yyewolf, I traced this on main at 92ac08a: in go/harness/runtime/a2a/executor.go, Executor.Cancel calls restorePending() before it looks at the task state.

    restorePending() reads the durable record only when e.state is nil. The Claude driver's RestorePending, in go/harness/claude/internal/driver/deferred.go, returns ErrSessionAbandoned for a record in phaseResuming or phaseExecuting. Say Substrate restores the data directory into a fresh harness, so the executor no longer holds the resumed turn as its activeTask. The answered record then reads as abandoned, and Cancel returns ErrSessionAbandoned before it can reach the live turn.

    A regression pair through Executor.Cancel with a restoring runner would pin it down. Cancel while parked should end TASK_STATE_CANCELED, as it does today. Cancel after the answer, with the record in phaseExecuting, should stop the turn or report that the outcome is unknown. I'd assert three things separately: what Cancel returned, whether the harness process exited, and what the target saw afterwards. In your run, that last one is the clone and the git push.

  2. arun-elr commented on Nov 11, 2026

    @arun-elr

    @yyewolf @astrogilda reproduced this on main (fbfd58a) on kind with the claude harness: answer an ask_user, then cancel while the resumed turn is in a model call. CancelTask fails after 30s with runtime cancellation cleanup failed: context deadline exceeded, and the session can't be deleted after that. kagent, codex and byo cancel fine.

    cause: on cancel the claude driver doesn't kill a replay process. it marks the journal canceling and waits up to 30s for claude to hit a hook and stop (process.go#L409-L423). once the replayed call has its result, no hook fires until the next tool call, so a long model call or tool (the git clone in this report) outlasts the wait. after the timeout Resume marks the journal abandoned, which is likely where the deferred continuation cannot be resumed error comes from on the next cancel.

    I have a fix: once the replayed call has its tool result, stop the rest of the turn like any other turn and record the journal as canceled, so a restored harness doesn't report it abandoned. a cancel before the result still waits for claude to settle the call. unit test plus an e2e test (ask, answer, hold the next model call, cancel) that fail on main and pass with it.

    @EItanya ok to assign this to me? branch: https://github.com/arun-elr/kagent/tree/fix-cancel-after-ask-user

  3. arun-elr commented on Nov 11, 2026

    @arun-elr

    @astrogilda @yyewolf draft PR up at #3647, so nobody doubles up on it.

    @astrogilda your trace of Executor.Cancel calling restorePending() before it looks at the task is the a2a half. The claude harness has its own: consume sets cancelReplay and then waits cancellationCleanupTimeout (30s) for a hook that never fires if Claude is mid model call, so CancelTask returns runtime cancellation cleanup failed: context deadline exceeded. The PR stops the turn once the replayed call's tool result has arrived, and records the journal as canceled so a restore does not read it as an unfinished replay.

    Happy to fold in the a2a side here if you would rather it were one change, or leave it to you and keep this one to the harness.

  4. EItanya commented on Nov 11, 2026

    @EItanya
    Contributor

    Assigned! Sorry been super busy at KubeCon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions