Skip to content

fix(server): treat blank taskId/contextId as absent in message/send - #1172

Merged
kabir merged 1 commit into
a2aproject:mainfrom
paulrutter:issue-1171
Sep 23, 2026
Merged

kabir merged 1 commit into
a2aproject:mainfrom
paulrutter:issue-1171

Conversation

@paulrutter

@paulrutter paulrutter commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Proto3 scalar fields have no wire-level presence, so a message that never set taskId/contextId and one that explicitly serialized them as "" are indistinguishable once they cross a transport that always serializes non-optional fields. DefaultRequestHandler only checked for null, so a blank taskId was mistaken for a reference to an existing task with id "" instead of a request to start a new task, causing a spurious TaskNotFoundError (or a raw backend error, depending on the TaskStore implementation) for legitimate new-task requests.

Normalize blank taskId/contextId to null once, at the top of onMessageSend/onMessageSendStream, mirroring the emptyToNull convention already used on the gRPC mapping path (A2ACommonFieldMapper). Also harden the public authorizeTaskAccess(String, ...) overload, which is called directly by transport handlers with a raw id. Message.Builder's taskId()/contextId() setters are annotated @nullable to match the record's own nullable fields, since normalization needs to pass null through them.

This fixes #1171

Description

Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Follow the CONTRIBUTING Guide.
  • Make your Pull Request title in the https://www.conventionalcommits.org/ specification.
    • Important Prefixes for release-please:
      • fix: which represents bug fixes, and correlates to a SemVer patch.
      • feat: represents a new feature, and correlates to a SemVer minor.
      • feat!:, or fix!:, refactor!:, etc., which represent a breaking change (indicated by the !) and will result in a SemVer major.
  • Ensure the tests pass
  • Appropriate READMEs were updated (if necessary)

Proto3 scalar fields have no wire-level presence, so a message that never
set taskId/contextId and one that explicitly serialized them as "" are
indistinguishable once they cross a transport that always serializes
non-optional fields. DefaultRequestHandler only checked for null, so a
blank taskId was mistaken for a reference to an existing task with id ""
instead of a request to start a new task, causing a spurious
TaskNotFoundError (or a raw backend error, depending on the TaskStore
implementation) for legitimate new-task requests.

Normalize blank taskId/contextId to null once, at the top of
onMessageSend/onMessageSendStream, mirroring the emptyToNull convention
already used on the gRPC mapping path (A2ACommonFieldMapper). Also harden
the public authorizeTaskAccess(String, ...) overload, which is called
directly by transport handlers with a raw id. Message.Builder's
taskId()/contextId() setters are annotated @nullable to match the
record's own nullable fields, since normalization needs to pass null
through them.

This fixes a2aproject#1171

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MKiygCWwiHF1q8R5MgWx18
@kabir

kabir commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

@paulrutter thanks!

@kabir
kabir merged commit 10d1bf6 into a2aproject:main Sep 23, 2026
19 checks passed
@paulrutter
paulrutter deleted the issue-1171 branch September 23, 2026 17:02
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]: Blank (empty-string) taskId/contextId on message/send is treated as a reference to an existing task instead of "start new task"

3 participants