Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Bug]: REST transport: getTask builds an invalid URL for single-digit historyLength

Open Beginner friendly
#1,197 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
java
Domain
api

Research direction

Start in client/transport/rest/src/main/java/io/a2aproject/a2a/client/transport/rest/RestTransport.java at getTask and inspect the URL formatting. Run RestTransportTest.testGetTask with a single-digit historyLength such as 5, then add regression coverage showing the generated URI is valid and the query has no padding; normalize the related format strings if included in the change.

Written by the indexing model from the issue text.

Description

What happened?

Summary

RestTransport.getTask builds the request URL with a String.format pattern that uses width specifiers (%2d) where argument-index specifiers (%2$d) were intended. For a single-digit historyLength (0–9), %2d left-pads the value with a space, producing historyLength= 5. A raw space is illegal in a URI, so java.net.URI.create(...) throws IllegalArgumentException: Illegal character in query, and the getTask call fails before any request is sent.

Affected code

client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java, in getTask:

url.append(String.format("/tasks/%1s?historyLength=%2d", taskQueryParams.id(), taskQueryParams.historyLength()));

In Java format syntax, an argument index requires a trailing $ (%2$d). Without it, %2d means "decimal, minimum width 2", and %1s means "string, minimum width 1" — these are width fields, not argument references. The %1s on the id is harmless only by accident (a UUID is always wider than 1, so nothing is padded); the %2d on the integer pads any single-digit value.

Reproduction

String.format("/tasks/%1s?historyLength=%2d", "de38c76d-d54c-436c-8b9f-4c2703648d64", 5);
// => "/tasks/de38c76d-d54c-436c-8b9f-4c2703648d64?historyLength= 5"
//                                                               ^ stray space

URI.create("https://host/tasks/de38c76d-d54c-436c-8b9f-4c2703648d64?historyLength= 5");
// => java.lang.IllegalArgumentException: Illegal character in query at index N: ...historyLength= 5

Behavior by value:

historyLength formatted query valid URI?
1–9 historyLength= N (leading space) ❌
0 n/a — getTask skips the query when historyLength <= 0 ✅
≥ 10 historyLength=NN ✅

So any getTask call with historyLength in 1–9 fails. This is the common case (clients typically request a small history window), which makes the practical impact high.

Why existing tests don't catch it

RestTransportTest.testGetTask uses new TaskQueryParams("...", 10) — a two-digit value that satisfies the width-2 field, so no space is injected and the URL stays valid. Single-digit values are never exercised.

Suggested fix

Drop the width (preferred) or use real positional indices:

// simplest
url.append(String.format("/tasks/%s?historyLength=%d", taskQueryParams.id(), taskQueryParams.historyLength()));

// or, if explicit indices are desired
url.append(String.format("/tasks/%1$s?historyLength=%2$d", taskQueryParams.id(), taskQueryParams.historyLength()));

Also recommend adding a regression test that calls getTask with a single-digit historyLength (e.g. 5) and asserts the resulting URL/query is well-formed.

Related occurrences (same specifier mistake, latent)

The same %Ns width-vs-index pattern appears on other URL-building sites in RestTransport.java (e.g. /tasks/%1s:cancel, /tasks/%1s/pushNotificationConfigs/%2s, /tasks/%1s:subscribe). These don't currently misbehave because their arguments are strings whose length exceeds the width, so no padding occurs — but they're the same bug waiting on a short/empty value and would be worth normalizing to %s in the same change.

Environment

  • Observed on the v1.x line (org.a2aproject.sdk) and the v0.3 line (io.github.a2asdk:0.3.3.Final); both contain the identical historyLength=%2d line, and it is still present on the latest main.
  • Transport: HTTP+JSON (REST). JSON-RPC transport is unaffected (it doesn't build this query).
Relevant log output

Code of Conduct
  • I agree to follow this project's Code of Conduct
Dominant language
Java
Stars
500
Forks
179
Avg merge
1d 9h
Merged PRs (30d)
40

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from a2aproject/a2a-java

All issues in a2aproject/a2a-java

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.