From 9007b342336f219abb06c70772b4a0b402281ad4 Mon Sep 17 00:00:00 2001 From: kksingh000 <122664891+kksingh000@users.noreply.github.com> Date: Tue, 6 Oct 2026 13:28:44 +0000 Subject: [PATCH] fix: apply host when both withHost and withOkHttpClient are set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pinecone.Builder.build() only applied withHost(...) inside the else branch of `if (customOkHttpClient != null)`, so an explicitly configured host was silently dropped whenever a custom OkHttpClient was also supplied — requests fell back to the default api.pinecone.io instead. Moves the host-setting logic (config.setHost / apiClient.setBasePath) out of that else branch so it always runs when a host is configured, regardless of which OkHttpClient path was taken. This matches the root-cause and fix already confirmed by a maintainer in the issue thread; a prior attempt at this exact fix (PR #210, via a Cursor background agent) was opened in January 2026 but closed unmerged in June 2026 without landing. Fixes #192 Testing: - Added PineconeWithHostAndCustomOkHttpClientUsesHost to PineconeBuilderTest, which builds a client with both withHost(...) and withOkHttpClient(...) and asserts the outgoing request's host and port match the configured host. - Verified empirically: with the fix reverted (source reset to the current main HEAD) the new test fails exactly as the issue describes (expected "my-custom-host" but was "api.pinecone.io"); with the fix restored it passes. - Full suite: `./gradlew clean build -x integrationTest` — BUILD SUCCESSFUL, 91/91 unit tests pass (90 pre-existing + 1 new), JDK 21. - integrationTest not run (needs PINECONE_API_KEY and live infrastructure); unaffected by this change since it only touches Builder.build()'s client construction path. This change, including the regression test and this PR description, was written with AI assistance (Claude). --- .../java/io/pinecone/clients/Pinecone.java | 13 +++++--- .../java/io/pinecone/PineconeBuilderTest.java | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/pinecone/clients/Pinecone.java b/src/main/java/io/pinecone/clients/Pinecone.java index 9d7cc082..9131a5ff 100644 --- a/src/main/java/io/pinecone/clients/Pinecone.java +++ b/src/main/java/io/pinecone/clients/Pinecone.java @@ -1778,11 +1778,16 @@ public Pinecone build() { apiClient = new ApiClient(customOkHttpClient); } else { apiClient = new ApiClient(buildOkHttpClient(proxyConfig)); - if(host!=null && !host.isEmpty()) { - config.setHost(host); - apiClient.setBasePath(host); - } } + + // Host must be applied regardless of which OkHttpClient path was used above, + // otherwise an explicitly configured host is silently ignored whenever a + // customOkHttpClient is also supplied. See https://github.com/pinecone-io/pinecone-java-client/issues/192 + if (host != null && !host.isEmpty()) { + config.setHost(host); + apiClient.setBasePath(host); + } + apiClient.setApiKey(config.getApiKey()); apiClient.setUserAgent(config.getUserAgent()); apiClient.addDefaultHeader("X-Pinecone-Api-Version", Configuration.VERSION); diff --git a/src/test/java/io/pinecone/PineconeBuilderTest.java b/src/test/java/io/pinecone/PineconeBuilderTest.java index 9557f973..8148bc69 100644 --- a/src/test/java/io/pinecone/PineconeBuilderTest.java +++ b/src/test/java/io/pinecone/PineconeBuilderTest.java @@ -78,6 +78,36 @@ public void PineconeWithOkHttpClientAndUserAgent() throws IOException { assertEquals("lang=java; pineconeClientVersion=" + pineconeClientVersion, requestCaptor.getValue().header("User-Agent")); } + @Test + public void PineconeWithHostAndCustomOkHttpClientUsesHost() throws IOException { + // Regression test for https://github.com/pinecone-io/pinecone-java-client/issues/192 -- + // withHost(...) must still be honored when a custom OkHttpClient is also supplied. + String filePath = "src/test/resources/serverlessIndexJsonString.json"; + String indexJsonStringServerless = new String(Files.readAllBytes(Paths.get(filePath))); + + AbstractMap.SimpleEntry mockCallAndClient = + buildMockCallAndClient(ResponseBody.create( + indexJsonStringServerless, + MediaType.parse("application/json"))); + + OkHttpClient mockClient = mockCallAndClient.getValue(); + + Pinecone client = new Pinecone.Builder("testAPiKey") + .withHost("http://my-custom-host:5080") + .withOkHttpClient(mockClient) + .build(); + // Create expected index after client creation to ensure JSON class is initialized + IndexModel expectedIndex = IndexModel.fromJson(indexJsonStringServerless); + IndexModel index = client.describeIndex("testIndex"); + + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Request.class); + + assertEquals(expectedIndex, index); + verify(mockClient, times(1)).newCall(requestCaptor.capture()); + assertEquals("my-custom-host", requestCaptor.getValue().url().host()); + assertEquals(5080, requestCaptor.getValue().url().port()); + } + @Test public void PineconeWithSourceTag() throws IOException { String filePath = "src/test/resources/serverlessIndexJsonString.json";