fix(server): reject a message whose contextId disagrees with its task - #1270
Merged
JakubWorek merged 2 commits intoSep 29, 2026
Merged
JakubWorek merged 2 commits into
JakubWorek merged 2 commits into
Conversation
🧪 Code Coverage (vs
|
| Base | PR | Delta | |
|---|---|---|---|
| src/a2a/server/request_handlers/default_request_handler_v2.py | 92.68% | 92.80% | 🟢 +0.12% |
| Total | 93.12% | 93.12% | ⚪️ 0.00% |
Generated by coverage-comment.yml
JakubWorek
added this pull request to stack #1275
September 23, 2026 12:55
JakubWorek
force-pushed
the
jakubworek/acts-context-id-mismatch
branch
from
September 23, 2026 13:11
2deb1c4 to
59afee4
Compare
JakubWorek
marked this pull request as ready for review
September 23, 2026 13:26
mykytanetipa
approved these changes
Sep 27, 2026
JakubWorek
force-pushed
the
jakubworek/acts-context-id-mismatch
branch
2 times, most recently
from
September 28, 2026 08:47
248bf73 to
12777b4
Compare
Spec 5.6 requires agents to reject mismatching contextId and taskId. RequestContext has carried that guard all along, but v2 calls build() with task=None on purpose, so nothing reached it and the client's contextId was written into the task's history beside the task's own. Checked against the task v2 already fetches to prove existence, and only when a taskId is present: a contextId on its own starts a new task in that context and stays legal.
JakubWorek
force-pushed
the
jakubworek/acts-context-id-mismatch
branch
from
September 28, 2026 10:14
12617cd to
49dfc35
Compare
mykytanetipa
pushed a commit
that referenced
this pull request
Sep 29, 2026
🤖 I have created a release *beep* *boop* --- ## [1.2.0](v1.1.5...v1.2.0) (2026-09-29) ### Features * **rest:** serve HTTP+JSON responses as application/a2a+json ([#1274](#1274)) ([dc5a5da](dc5a5da)) * **server:** add caching headers to the agent card endpoint ([#1272](#1272)) ([83d7f5d](83d7f5d)) * **server:** add multi-replica cluster mode ([#1281](#1281)) ([942d621](942d621)) * **server:** add opt-in validation of message media types against the agent card ([#1269](#1269)) ([8037b24](8037b24)) ### Bug Fixes * compare in-memory task timestamps numerically ([#1233](#1233)) ([0d5473c](0d5473c)) * **server:** ignore unrecognized request fields and fix parse-error data shape ([#1273](#1273)) ([83f1cf8](83f1cf8)) * **server:** reject a message whose contextId disagrees with its task ([#1270](#1270)) ([c25022f](c25022f)) * **server:** reject terminal-task operations with UnsupportedOperationError ([#1268](#1268)) ([6cce91b](6cce91b)) * **server:** send PushNotificationConfig.authentication as an Authorization header ([#1271](#1271)) ([5751d31](5751d31)), closes [#585](#585) ### Documentation * **samples:** add Agent Card signing sample ([#1198](#1198)) ([f3ac824](f3ac824)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
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
Spec 3.4.3: "Agents MUST reject messages containing mismatching
contextIdandtaskId(i.e., the providedcontextIdis different from that of the referencedTask)."A follow-up carrying a real
taskIdwith someone else'scontextIdwas accepted with HTTP 200, and the client'scontextIdwas then written into the task's history while theTaskkept its own - two disagreeing context ids inside one task.This guard already existed
RequestContexthas carried it all along (agent_execution/context.py:77-78). It only fires when a non-Nonetaskreachesbuild(), and v2 passestask=Noneon purpose:So the check went dead when V2 became the default. The legacy handler passes the task and still rejects.
Rather than undo that deliberate
task=None, the comparison goes where v2 already fetches the task to prove it exists, one line after theTaskNotFoundErrorit raises there. No extra read, and the task is not retained.Scoped to requests that name a task
The check only runs under
if original_task_id:. AcontextIdwith notaskIdis a new task in an existing context, which stays legal -test_scenario_context_id_visibilitydepends on it, and there is a test here pinning it.A test that passed for the wrong reason
Worth flagging for review.
TaskManageralready rejects this mismatch once the agent emits an event, withContext in event doesn't match TaskManager wrong-context : real-context. That message happens to contain both context ids, so the obvious assertion -pytest.raises(InvalidParamsError)plus both ids in the message - passes with or without this change. It did, and mutation testing is what caught it.The test now asserts the executor was never awaited. That is the actual behavioural difference: the request is refused before any agent work starts, instead of after the agent has already been handed a request whose ids contradict each other.
Result
Clears
CORE-MULTI-006(must) on all three bindings.