fix: task.cancel()/retry() during kernel close must not raise#1188
Merged
Conversation
_drop_call_state (registered via context.on_close to unpin contexts at kernel close) drops the call bookkeeping including _cancel/_retry, but the reactive state still reads pending at that point. Application cleanup code running later in the same close - the common pattern `if task.pending: task.cancel()` - then hit "RuntimeError: Cannot cancel task, never started", producing three tracebacked warnings per kernel close in a production app (heavy log/ Sentry noise; functionally harmless). A task that ran always has _cancel set, so "state is not NOTCALLED but _cancel is None" can only mean the call state was dropped: make cancel() and retry() a no-op there and keep raising only for genuinely never-started tasks. Regression test reproduces the production ordering (on_close callbacks run LIFO, so a guard registered before the task starts runs after the drop). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by integration-testing current master in a large solara application: three tracebacked warnings on every kernel close, from
RuntimeError: Cannot cancel task, never started.Sequence
@taskruns;_drop_call_stateis registered viacontext.on_close(the recent memory fix that unpins contexts at close)._drop_call_statenulls_cancel/_retry/futures — but the reactive state still readspending.if task.pending: task.cancel()→cancel()finds_cancel is None→ raises "never started", which is wrong on both counts: it started, and there is simply nothing left to cancel.Fix
A task that ran always has
_cancelset, so state ≠ NOTCALLED with_cancel is Nonecan only mean the call state was dropped at close:cancel()/retry()are now a no-op in that case, and keep raising only for genuinely never-started tasks (misuse detection unchanged).The regression test reproduces the production ordering:
on_closecallbacks run LIFO, so a guard registered before the task starts runs after_drop_call_state. Verified: fails on master with exactly the production error, passes with the fix; full task suite (24) green.🤖 Generated with Claude Code