Skip to content

fix: validate task ID length and message content - #1176

Open
ez-lbz wants to merge 2 commits into
a2aproject:mainfrom
ez-lbz:fix/input-validation
Open

fix: validate task ID length and message content#1176
ez-lbz wants to merge 2 commits into
a2aproject:mainfrom
ez-lbz:fix/input-validation

Conversation

@ez-lbz

@ez-lbz ez-lbz commented Aug 10, 2026

Copy link
Copy Markdown

What changed

1. Reject over-long task IDs before persistence

Problem: No upper bound is enforced on taskId. A client can send a 1000+ character task ID in tasks/get, tasks/cancel, message/send, SubscribeToTask or any push-notification-config method and the ID is passed straight to the task store and persisted. There is also no check that a provided task ID is non-empty. Affected files: src/a2a/server/request_handlers/default_request_handler.py, src/a2a/server/request_handlers/default_request_handler_v2.py.

Fix (src/a2a/utils/task.py, src/a2a/server/request_handlers/default_request_handler.py, src/a2a/server/request_handlers/default_request_handler_v2.py):

  • Added MAX_TASK_ID_LENGTH = 1000 and validate_task_id() in src/a2a/utils/task.py; it raises InvalidParamsError for empty task IDs or IDs longer than 1000 characters.
  • Applied validate_task_id() at the entry of every task-ID-taking handler method in both V1 (LegacyRequestHandler) and V2 (DefaultRequestHandlerV2): on_get_task, on_cancel_task, on_subscribe_to_task, on_message_send/on_message_send_stream (via _setup_message_execution/_setup_active_task, only when a task ID is supplied) and the four push-notification-config methods. Validation happens before any store read/write.

2. Reject messages with empty content

Problem: MessageSend accepts messages with no parts or with parts that carry no content (no text, raw, url or non-null data). Such empty payloads are persisted into task history. The framework's schema validation already rejects an empty parts list with InvalidParamsError ("Validation failed"), but a part with no content (e.g. only media_type set) passes through unchecked.

Fix (src/a2a/utils/task.py, src/a2a/server/request_handlers/default_request_handler.py, src/a2a/server/request_handlers/default_request_handler_v2.py):

  • Added validate_message_content() in src/a2a/utils/task.py, which raises InvalidParamsError if the message has no parts or any part is empty (no text/raw/url, and data is unset or null).
  • Called it in _setup_message_execution (V1) and _setup_active_task (V2), which both on_message_send and on_message_send_stream route through, so the check applies to the streaming path too.

Testing

  • ./.venv/Scripts/python -m pytest tests/utils/test_task.py tests/server/request_handlers/test_default_request_handler.py tests/server/request_handlers/test_default_request_handler_v2.py -q159 passed (includes 13 new regression tests: task-ID length limits and empty-content rejection at both the utility and handler level).
  • ./.venv/Scripts/python -m ruff check on all modified files: clean (the two too-many-positional-arguments findings on the handler __init__ lines pre-date this change and exist on main).
  • Behavior change: requests with over-long/empty task IDs and messages with empty content now return InvalidParamsError instead of being processed. This is the intended hardening; clients must send valid task IDs and non-empty message content.

@ez-lbz
ez-lbz requested a review from a team as a code owner August 10, 2026 16:08
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown

🧪 Code Coverage (vs main)

⬇️ Download Full Report

Base PR Delta
src/a2a/server/events/event_queue_v2.py 91.79% 91.28% 🔴 -0.51%
src/a2a/server/request_handlers/default_request_handler.py 98.13% 98.20% 🟢 +0.07%
src/a2a/server/request_handlers/default_request_handler_v2.py 94.17% 94.47% 🟢 +0.30%
src/a2a/utils/task.py 95.16% 96.70% 🟢 +1.54%
src/a2a/utils/telemetry.py 91.47% 90.70% 🔴 -0.78%
Total 93.00% 93.02% 🟢 +0.02%

Generated by coverage-comment.yml

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.

1 participant