You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HttpRequest.url() logs spaces in path segments as literal plus signs #886
HttpRequest.url() uses URLEncoder for both query components and path segments:
append(URLEncoder.encode(segment, "UTF-8"))
URLEncoder applies form/query encoding semantics, where a space becomes +. That is valid for the query-string usage in the same method, but a + in a URL path is a literal plus character rather than a space escape.
The actual OkHttp transport does not use this string to construct requests. It calls HttpUrl.Builder.addPathSegment("user name"), which sends the path as user%20name. LoggingHttpClient, however, prints request.url(), so the SDK log can show a different request target from the URL that was actually sent.
Expected behavior
HttpRequest.url() should percent-encode spaces in path segments as %20, while preserving the current + encoding for spaces in query parameters.
Impact
This is an observability/debugging correctness issue. Logs produced by LoggingHttpClient can misrepresent path parameters containing spaces, making reproduced requests target a different resource.
Suggested fix
Keep the existing form encoding for query components, but normalize the encoded path-segment result from + to %20. A literal + remains safe because URLEncoder already represents it as %2B.
Thanks for raising this, and for putting together #887! It fixes the path-space case you reported in HttpRequest.url(). That's a useful correction, but it doesn't cover every case where the URL rendered by that method differs from the one OkHttp prepares. For example, in Java:
importcom.openai.core.http.HttpMethod;
importcom.openai.core.http.HttpRequest;
HttpRequestpunctuation = HttpRequest.builder()
.method(HttpMethod.GET)
.baseUrl("https://example.com/v1")
.addPathSegment("a!b")
.build();
// punctuation.url() after #887: https://example.com/v1/a%21b// URL prepared by OkHttp: https://example.com/v1/a!bHttpRequestexistingQuery = HttpRequest.builder()
.method(HttpMethod.GET)
.baseUrl("https://example.com/v1?x=1")
.putQueryParam("y", "2")
.build();
// existingQuery.url() after #887: https://example.com/v1?x=1?y=2// URL prepared by OkHttp: https://example.com/v1?x=1&y=2
I've opened #997 to address the logging mismatch more generally. With INFO logging and the default OkHttp transport, it logs the initial URL OkHttp prepared instead of independently reconstructing one from HttpRequest.url(), so the log reflects OkHttp's URL in both examples. It doesn't change HttpRequest.url() or the request sent, and a later interceptor or redirect can still change the destination. Your fix in #887 remains valuable for callers of HttpRequest.url() itself. Thanks again for the thoughtful report and PR!
Thanks, that distinction makes sense. #887 can stay focused on correcting HttpRequest.url() itself, while #997 handles the broader transport-log mismatch by using the URL OkHttp actually prepared.
Activity
dpiet-oai commentedon Sep 14, 2026
Thanks for raising this, and for putting together #887! It fixes the path-space case you reported in
HttpRequest.url(). That's a useful correction, but it doesn't cover every case where the URL rendered by that method differs from the one OkHttp prepares. For example, in Java:I've opened #997 to address the logging mismatch more generally. With INFO logging and the default OkHttp transport, it logs the initial URL OkHttp prepared instead of independently reconstructing one from
HttpRequest.url(), so the log reflects OkHttp's URL in both examples. It doesn't changeHttpRequest.url()or the request sent, and a later interceptor or redirect can still change the destination. Your fix in #887 remains valuable for callers ofHttpRequest.url()itself. Thanks again for the thoughtful report and PR!sylvesterkaczmarek commentedon Sep 14, 2026
Thanks, that distinction makes sense. #887 can stay focused on correcting
HttpRequest.url()itself, while #997 handles the broader transport-log mismatch by using the URL OkHttp actually prepared.