[Bug]: taskId-only continuation still fails required contextId inference in SDK 1.3.0 (follow-up to #1206)
维护者通常 2 天内回复
@rohityan 已经在做这个了。
开始于 2026年11月1日。
评估
这个 Issue 还没有评估数据。
描述
What happened?
With a2a-sdk==1.3.0 (Python 3.13), continuing an existing task with only message.task_id assigns a fresh context_id to the executor and its status events. The canonical stored Task still has the original context, so the execution/events disagree with GetTask.
A2A v1.0.1 §3.4.3 requires: "Agents MUST infer contextId from the task" when only taskId is provided. This affects applications using contextId as a checkpoint/thread key.
Previous report and current evidence
This follows #1206, which was closed by the stale bot as not_planned on 2026-09-24, rather than resolved by a fix. Its closing message explicitly asks for a new issue if assistance is still needed. A maintainer suggested overriding _setup_active_task as a temporary workaround.
The behavior below is newly reproduced against released 1.3.0. It is distinct from #1285 (continuation stream snapshot/history) and #1409 (stale blocking INPUT_REQUIRED response). The reproducer emits Task only for the first execution and uses a streaming continuation to isolate context inference.
Minimal reproduction
Install a2a-sdk==1.3.0 and run:
import asyncio
from uuid import uuid4
from a2a.server.agent_execution import AgentExecutor
from a2a.server.context import ServerCallContext
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.tasks import InMemoryTaskStore, TaskUpdater
from a2a.types import (AgentCard, AgentCapabilities, AgentInterface, AgentSkill,
Message, Part, SendMessageRequest, Task, TaskState, TaskStatus, GetTaskRequest)
class Agent(AgentExecutor):
def __init__(self):
self.contexts = []
async def execute(self, context, queue):
self.contexts.append(context.context_id)
if context.current_task is None:
await queue.enqueue_event(Task(id=context.task_id, context_id=context.context_id,
status=TaskStatus(state=TaskState.TASK_STATE_SUBMITTED), history=[context.message]))
updater = TaskUpdater(queue, context.task_id, context.context_id)
if context.current_task is None:
await updater.requires_input()
else:
await updater.start_work()
await updater.complete()
async def cancel(self, context, queue):
await TaskUpdater(queue, context.task_id, context.context_id).cancel()
async def main():
agent = Agent()
card = AgentCard(name='Repro', description='Task-only context inference', version='1',
capabilities=AgentCapabilities(streaming=True),
default_input_modes=['text/plain'], default_output_modes=['text/plain'],
supported_interfaces=[AgentInterface(url='http://localhost/a2a', protocol_binding='JSONRPC', protocol_version='1.0')],
skills=[AgentSkill(id='repro', name='Repro', description='Pause and resume', tags=['repro'])])
handler = DefaultRequestHandler(agent_executor=agent, task_store=InMemoryTaskStore(), agent_card=card)
caller = ServerCallContext()
def request(text, task_id=''):
return SendMessageRequest(message=Message(message_id=str(uuid4()), role=1,
parts=[Part(text=text)], task_id=task_id))
try:
first = await handler.on_message_send(request('Analyze'), caller)
events = [event async for event in handler.on_message_send_stream(request('EU', first.id), caller)]
canonical = await handler.on_get_task(GetTaskRequest(id=first.id), caller)
print('stored task context:', first.context_id)
print('continuation executor context:', agent.contexts[-1])
print('continuation event contexts:', [event.context_id for event in events])
print('canonical task context:', canonical.context_id)
print('inherited:', agent.contexts[-1] == first.context_id)
assert agent.contexts[-1] != first.context_id
assert canonical.context_id == first.context_id
finally:
await handler.aclose()
asyncio.run(main())
Observed (UUIDs vary):
stored task context: 357aa773-df63-492d-a210-03f26c9eed1c
continuation executor context: 765135ce-f891-4476-a911-5397216d6a26
continuation event contexts: ['765135ce-f891-4476-a911-5397216d6a26', '765135ce-f891-4476-a911-5397216d6a26']
canonical task context: 357aa773-df63-492d-a210-03f26c9eed1c
inherited: False
Expected behavior / suggested regression
Load the existing task through the caller-scoped store before allocating a context for a task-only request. Use its context for RequestContext and every returned event; do not generate a replacement context. Preserve unknown/inaccessible TaskNotFound semantics and explicit task/context mismatch validation.
A regression should assert the executor context, all streamed event contexts, and the canonical Task context are equal for task-only continuation, in both blocking and streaming modes. Our local workaround infers the context through authorized GetTask before delegating; we keep it until an unpatched upgraded SDK passes those checks.
Code of Conduct
- I agree to follow this project's Code of Conduct
- 主要语言
- Python
- 星标
- 2.2k
- 派生
- 528
- 平均合并
- 3 天 17 小时
- 30 天内合并 PR
- 43
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
a2aproject/a2a-python 的其他 Issue
-
[Bug]: `A2A-Version` validation ignores minor versions and the query parameter可能已有人在做 @rohityan 于 69 天前认领。 未关闭component: server status:awaiting response
难度 2/5 1-3 小时 新手友好度 75/100
a2aproject/a2a-python#1204 · 3 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
-
[Bug]: REST task/request id sanitization可能已有人在做 @Linux2010 于 128 天前认领。 未关闭maintainers-only
难度 2/5 1-3 小时 新手友好度 65/100
a2aproject/a2a-python#805 · 1 条评论 ·
维护者通常 2 天内回复
-
[Bug]: CancelTaskRequest.metadata never reaches AgentExecutor.cancel可能已有人在做 @muscariello 今天认领。 未关闭maintainers-only
a2aproject/a2a-python#1415 · 已指派 1 人 ·
维护者通常 2 天内回复
-
[Feat]: Add a task-state-invariants agent skill for sibling-surface propagation可能已有人在做 @Linux2010 今天认领。 未关闭component: tooling status:awaiting response
a2aproject/a2a-python#1413 · 3 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
-
[Feat]: Add a PermissionDenied server error with HTTP 403 and gRPC PERMISSION_DENIED mappings可能已有人在做 @Iwaniukooo11 今天认领。 未关闭component: core status: needs review
a2aproject/a2a-python#1410 · 2 条评论 · 已指派 2 人 ·
维护者通常 2 天内回复
查看 a2aproject/a2a-python 的全部 Issue
相似的 Issue
-
ci-rerun: collect.py fails a whole pr-babysit cycle on one transient GitHub 5xx and never retries未关闭follow-up
难度 2/5 1-3 小时 新手友好度 62/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
-
Built-in QUBO fallback applies bitwise xor to floating binary states可能已有人在做 @iloveeyjafjalla 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
qboson/kaiwu-pytorch-plugin#1702 ·
维护者通常 3 天内回复
-
bug v2
难度 2/5 1-3 小时 新手友好度 76/100
modelcontextprotocol/python-sdk#3811 ·
维护者通常 1 天内回复
-
cost:cheap practicality:seen-in-the-wild severity:medium
难度 2/5 1-3 小时 新手友好度 72/100
fairagro/m4.2_advanced_middleware_api#620 ·
维护者通常 1 天内回复