Spec proposal: bounded input limits — task ID length, history_length, push notification configs per task
- Lenguaje dominante
- Shell
- Estrellas
- 25.7k
- Forks
- 2.6k
- Merge medio
- 3 d 6 h
- PR fusionados (30 d)
- 16
Descripción
## Summary
The spec defines no bounded limits for several protocol inputs that map directly to server-side storage and memory. Three hardening changes were implemented in the Python SDK (PRs below) and parallel ones exist for the JavaScript SDK, but the SDK maintainers correctly deferred them: **resource limits like these are public-facing behavioral semantics and belong in the spec first** (see the review guidance quoted at the bottom). This issue proposes the spec-level decision.
## Problem
Today a client can, on every transport (§5.1 functional equivalence applies to all of them):
1. **Send arbitrarily long task IDs** (1000+ chars) — or empty ones — which are persisted into the task store (`tasks/get`, `tasks/cancel`, `message/send`, `tasks/resubscribe`, all push-notification-config methods).
2. **Send `historyLength` = 999999999** — the server materializes the full history of every matching task in `tasks/get`, `tasks/list`, and `message/send`.
3. **Register an unbounded number of push notification configs per task** — each entry is a persistent webhook endpoint the server will call.
None of these has a spec-sanctioned bound or a canonical "input exceeds limit" error, so every SDK has to invent its own — or leave the hole open.
## Proposal
Define canonical, recommended-default limits in the spec (exact values are debatable; the SDK PRs propose these):
| Input | Proposed default | Excess behavior | SDK evidence |
|---|---|---|---|
| Task ID | non-empty, ≤ 1000 chars | `INVALID_PARAMS` (-32602 / HTTP 400) before any store access | a2a-python#1176, empty-ID check also in a2a-js#629 |
| `historyLength` | ≤ 1000 (large value ≈ "everything" stays valid below the cap) | `INVALID_PARAMS` (-32602 / HTTP 400) | a2a-python#1177, a2a-js#639 |
| Push notification configs per task | ≤ 50 | `INVALID_PARAMS` (-32602 / HTTP 400) on create beyond the cap | a2a-python#1181, a2a-js#635 |
Questions for the spec maintainers:
- Are these the right categories to bound, and are the default values reasonable as **recommended** defaults (MUST reject vs MAY enforce)?
- Should exceeding the push-config cap be `INVALID_PARAMS`, or a dedicated error name (e.g. `PushConfigLimitExceeded`)?
- Any additional inputs that deserve the same treatment for consistency (e.g. metadata size, context ID length)?
## Why it matters
- **Robustness/DoS**: unbounded IDs and per-task config lists are unbounded persistent storage; an unbounded `historyLength` is an unbounded read amplification.
- **Cross-SDK consistency**: clients need identical limits and identical error semantics across Python/JS/Java/Go SDKs — otherwise "valid" against one server fails against another with different errors.
- **Clean review path**: the SDK changes already exist and are tested; once the spec fixes the semantics, they can be aligned and merged.
## References
- a2a-python#1176 — validate task ID length and message content
- a2a-python#1177 — enforce upper bound on history_length
- a2a-python#1181 — cap push notification configs per task
- a2a-js#629 / a2a-js#639 / a2a-js#635 — the same hardening batch in the JavaScript SDK
- #2126 — related: canonical errors for push-notification-config operations
- a2a-python review guidance (2026-09-08): *"it's a public-facing behavioral change, so it should be reviewed and accepted by the A2A spec maintainers first. Please open a spec proposal … before implementing it in the SDK."*
Happy to turn this into a spec PR once there is agreement on the semantics.
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.