fix: validate task state transitions (block terminal escape) - #1182
Open
ez-lbz wants to merge 2 commits into
Open
fix: validate task state transitions (block terminal escape)#1182ez-lbz wants to merge 2 commits into
ez-lbz wants to merge 2 commits into
Conversation
🧪 Code Coverage (vs
|
| Base | PR | Delta | |
|---|---|---|---|
| src/a2a/server/events/event_queue_v2.py | 91.79% | 91.28% | 🔴 -0.51% |
| src/a2a/server/tasks/task_manager.py | 98.68% | 98.74% | 🟢 +0.06% |
| src/a2a/utils/telemetry.py | 91.47% | 90.70% | 🔴 -0.78% |
| Total | 93.00% | 92.98% | 🔴 -0.02% |
Generated by coverage-comment.yml
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.
What changed
1. Validate task state transitions before persisting status updates
Problem:
TaskManager.save_task_event()(src/a2a/server/tasks/task_manager.py) blindly overwrote the task status withtask.status.CopyFrom(event.status)for everyTaskStatusUpdateEvent. A misbehaving or malicious agent could move a task that is already in a terminal state (COMPLETED/CANCELED/FAILED/REJECTED) back to SUBMITTED (or to another state), rewriting the persisted terminal outcome.active_task.py:571was already guarded (if task.status.state not in TERMINAL_TASK_STATES) and needed no change.Fix (src/a2a/server/tasks/task_manager.py):
TERMINAL_TASK_STATESandvalidate_state_transition(current_state, new_state), which raisesInvalidAgentResponseErrorwhen a terminal state would transition to any different state (including back to SUBMITTED). Re-persisting the same terminal state is tolerated for idempotency, and all forward transitions (SUBMITTED→WORKING→terminal, interrupted states, etc.) are unaffected.save_task_event()now callsvalidate_state_transition()beforetask.status.CopyFrom(...). Both the V1 path (ResultAggregator →TaskManager) and the V2 path (ActiveTaskEventConsumer →TaskManager) flow through this single chokepoint.Testing
./.venv/Scripts/python -m pytest tests/server/tasks/test_task_manager.py -q→ 29 passed (includes new tests: parametrized rejection of every terminal→other transition, acceptance of legal forward/idempotent transitions, and an end-to-endsave_task_eventregression test asserting a completed task cannot be moved back to SUBMITTED and the store is unchanged)../.venv/Scripts/python -m pytest tests/server/request_handlers/ tests/server/agent_execution/ tests/server/tasks/ tests/server/events/ -q→ 551 passed, 90 skipped, 3 xfailed (pre-existing xfails reference upstream issue [Feat]: Improve server concurrency architecture #869)../.venv/Scripts/python -m ruff checkon modified files: clean.InvalidAgentResponseError(-32006) instead of silently overwriting the persisted state. All legitimate agent flows (including REJECTED/CANCELED) are unaffected.