Skip to content

fix(turn): clear active slot on cancel to avoid phantom -32003 - #304

Open
icn5381 wants to merge 1 commit into
EverMind-AI:mainfrom
icn5381:fix/turn_cancel_clears_active
Open

fix(turn): clear active slot on cancel to avoid phantom -32003#304
icn5381 wants to merge 1 commit into
EverMind-AI:mainfrom
icn5381:fix/turn_cancel_clears_active

Conversation

@icn5381

@icn5381 icn5381 commented Aug 12, 2026

Copy link
Copy Markdown

Summary

turn.cancel relied on the sink's on_turn_end callback (fired from _drop at turn exit) to clear the _active_turns slot, and awaited handle.result() assuming the sink had already dropped it. A cancelled turn can resolve before that callback runs, so the slot was sometimes left populated and the next turn.send hit a phantom turn_in_progress (-32003).

Call clear_active from turn_cancel itself after the drain. pop is idempotent, so the sink's later clear is a harmless no-op.

Type

  • Fix

Verification

  • Relevant tests pass locally: uv run pytest tests/test_turn_cancel_clears_active.py -v -> 2 passed
  • Relevant lint / type checks pass locally: uv run ruff format (2 files unchanged), uv run ruff check (all passed)
  • User-facing docs or screenshots updated: N/A (internal lifecycle fix)

Risk

  • Security impact considered: only clears an in-memory turn slot the caller already owns; no new input, no shell
  • Backward compatibility considered: clear_active pops with a default and is already the sink's turn-end path, so the added call is additive and idempotent
  • Rollback path is clear: revert restores the sink-only clear

Related Issues

Fixes #115

turn.cancel relied on the sink's on_turn_end callback (fired from _drop at
turn exit) to clear the _active_turns slot, and awaited handle.result()
assuming the sink had already dropped it. A cancelled turn can resolve
before that callback runs, so the slot was sometimes left populated and
the next turn.send hit a phantom turn_in_progress (-32003).

Call clear_active from turn_cancel itself after the drain. pop is
idempotent, so the sink's later clear is a harmless no-op.

Co-authored-by: Claude (claude-opus-5) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug:Turn state remains locked after prompt cancellation/interruption

1 participant