Skip to content

fix(http): send spaces in query parameters as %20, not + - #707

Open
tanvir-ux wants to merge 1 commit into
pinecone-io:mainfrom
tanvir-ux:fix/query-param-space-encoding
Open

tanvir-ux wants to merge 1 commit into
pinecone-io:mainfrom
tanvir-ux:fix/query-param-space-encoding

Conversation

@tanvir-ux

@tanvir-ux tanvir-ux commented Oct 27, 2026 •

Copy link
Copy Markdown

Fixes #705

Problem

httpx encodes a space in a query value as +. The Pinecone API reads + as a literal plus sign, so fetch(ids=["doc 42"]) asked for doc+42, and a namespace named my ns was looked up as my+ns. fetch, list_paginated and list_namespaces(prefix=...) found nothing and raised no error. 8.1.2 sent %20 (#372); the move to httpx in 9.0.0 lost that.

Fix

httpx has no option to choose this encoding for params=, so HTTPClient and AsyncHTTPClient now encode params= themselves and append it to the request path, which httpx leaves as written (new helper _fold_params_into_path). The encoding is httpx's own, with spaces written as %20. urlencode already writes a real + as %2B, so a literal plus is still sent as %2B. Enum members are still resolved first. This covers every get/post/put/patch/delete that passes params=, sync and async, not only the three calls from the report. The post fast path (JSON body only) is unchanged.

Tests

New tests/unit/test_query_param_space_encoding_705.py (20 tests) checks the raw request target for all five verbs on both clients, a literal + and % staying distinct from a space, enum resolution, params added to a query already in the path, empty params, and fetch, list_paginated and list_namespaces(prefix=...) on Index and AsyncIndex. 18 of the 20 fail on main without the change and pass with it. The other 2 cover behaviour that was already correct and must stay that way.

Run locally:

  • pytest tests/unit: 11152 passed, 3 skipped
  • ruff check, ruff format --check and mypy on pinecone and the new test file: clean

I did not run the integration tests, as they need a live API key.


Note

Medium Risk
Central HTTP-layer change affects all requests that pass params=; incorrect encoding could break lookups, but behavior is narrowly scoped and heavily unit-tested.

Overview
Fixes #705: query parameters with spaces were sent as + (httpx default) while Pinecone treats + as a literal plus, so namespaces/IDs like "my ns" or "doc 42" silently failed to match after the 9.0 httpx migration.

_fold_params_into_path encodes params= with httpx’s QueryParams, rewrites + to %20, merges the string onto the request path, and drops params from kwargs so httpx does not re-encode. Literal + values stay %2B; enum query values are still normalized via _prepare_params. Wired into every sync/async get/post/put/patch/delete on HTTPClient / AsyncHTTPClient (POST JSON-only fast path unchanged).

Adds tests/unit/test_query_param_space_encoding_705.py with HTTP-boundary checks for all verbs and end-to-end coverage for fetch, list_paginated, and list_namespaces(prefix=...) on Index / AsyncIndex.

Reviewed by Cursor Bugbot for commit 9ecbcce. Bugbot is set up for automated code reviews on this repo. Configure here.

httpx encodes a space in a query value as '+', which the Pinecone API
reads as a literal plus sign. fetch(), list_paginated() and
list_namespaces(prefix=...) therefore found nothing for IDs or
namespaces containing a space. Encode params= into the request path so
spaces go out as %20, as they did before the move to httpx.

Fixes pinecone-io#705

This branch has not been deployed

No deployments
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.

[Bug] Spaces in IDs and namespaces sent as "+" in GET requests since 9.0.0 (regression of #372)

1 participant