Skip to content

Reset content-type when sending request - #1241

Merged
Strift merged 1 commit into
mainfrom
fix-reset-content-type
Jun 16, 2026
Merged

Reset content-type when sending request#1241
Strift merged 1 commit into
mainfrom
fix-reset-content-type

Conversation

@StephaneRob

@StephaneRob StephaneRob commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Pull Request

Related issue

Fixes meilisearch/meilisearch#6188

What does this PR do?

  • reset content-type when sending request to meilisearch; for example, when chaining two requests like swap_indexes and delete_index, the first request set content-type to application/json and the delete request use it with incorrect null body for this type.

PR checklist

Please check if your PR fulfills the following requirements:

  • Did you use any AI tool while implementing this PR (code, tests, docs, etc.)? If yes, disclose it in the PR description and describe what it was used for. AI usage is allowed when it is disclosed.
  • Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
  • Have you read the contributing guidelines?
  • Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!

Changes

  • Updated HttpRequests.send_request() and HttpRequests.post_stream() to remove any existing Content-Type header from a reused HttpRequests instance when the content_type parameter is falsy/omitted.
  • Added a regression test test_reset_content_type_header in tests/client/test_http_requests.py to verify the header is cleared after a request that doesn’t specify a content type.

Rationale

When chaining multiple requests with the same HTTP client, a prior request (e.g., one that sets Content-Type: application/json such as swap_indexes) could leave the header in place. A subsequent request without a body (e.g., deleting the temporary index) could be sent with a stale Content-Type, leading to server errors.

Impact

  • Prevents stale Content-Type headers from being carried across sequential requests
  • Fixes the failure scenario reported in issue #6188 where deleting an index right after swap_indexes could return a 500 on remote Meilisearch instances

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

HttpRequests.send_request and HttpRequests.post_stream now explicitly remove the Content-Type header from internal headers when content_type is omitted or falsy, preventing accidental header carryover across sequential requests that reuse the same client instance. A test validates the cleanup behavior.

Changes

HTTP Header Management Fix

Layer / File(s) Summary
Content-Type header cleanup in send_request and post_stream
meilisearch/_httprequests.py
Both send_request (line 52-53) and post_stream (line 167-168) now explicitly delete the Content-Type header from self.headers when content_type is falsy, preventing prior values from carrying over to subsequent requests made with the same HttpRequests instance.
Test validation for Content-Type header cleanup
tests/client/test_http_requests.py
A new test_reset_content_type_header function with supporting import verifies that send_request removes the Content-Type header when no content type is provided, confirming the fix prevents header carryover across sequential requests.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

🐰 Headers were sticky, requests got muddy,
But now we delete what's left from yesterday's buddy!
Both methods shine bright with explicit care—
No more secrets hiding in the shared request air! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: resetting the Content-Type header when sending requests, which directly addresses the root cause of the bug.
Linked Issues check ✅ Passed The changes correctly implement the fix for issue #6188 by ensuring the Content-Type header is reset when no content-type parameter is provided, preventing header persistence across sequential requests.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the Content-Type header issue described in #6188; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-reset-content-type

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@meilisearch/_httprequests.py`:
- Around line 50-53: The code mutates shared self.headers; instead create a
per-request copy (e.g., headers = self.headers.copy()) inside the HttpRequests
method that contains this snippet, set or pop "Content-Type" on that local
headers variable instead of self.headers, and pass that local headers into the
underlying HTTP call (requests.request/Session.request) so the global
self.headers is never mutated and concurrent requests cannot race.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d96d39b7-6be1-4f79-95dc-b38eab0a319d

📥 Commits

Reviewing files that changed from the base of the PR and between 218d8eb and d4d223f.

📒 Files selected for processing (1)
  • meilisearch/_httprequests.py

Comment thread meilisearch/_httprequests.py
@Strift Strift added the bug Something isn't working label Jun 15, 2026

@Strift Strift left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @StephaneRob, thanks for your PR - sorry that the issue ended up in the Meilisearch repo instead of here 😅

This looks good; it's just missing finishing touches:

  • Update post_stream with the same else branch
  • Add a unit test in tests/client/test_http_requests.py proving the header is reset

@StephaneRob
StephaneRob force-pushed the fix-reset-content-type branch 2 times, most recently from 9fcfb24 to 3780318 Compare June 15, 2026 07:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/client/test_http_requests.py (2)

33-43: ⚡ Quick win

Consider mocking the HTTP request for better test isolation.

The test makes an actual HTTP request to the health endpoint but discards the response, testing only the side effect on http.headers. Existing tests in this file are pure unit tests. Mocking requests.get would make this a true unit test, avoiding external dependencies and improving speed and reliability.

♻️ Proposed refactor using unittest.mock
+import unittest.mock
+
 import requests
 from meilisearch._httprequests import HttpRequests
 from meilisearch.config import Config
 def test_reset_content_type_header():
     """Tests that the content type header is reset when no content type is provided."""
     config = Config(BASE_URL, MASTER_KEY, timeout=None)
     http = HttpRequests(config=config)
 
     http.headers["Content-Type"] = "application/json"
     assert http.headers["Content-Type"] == "application/json"
 
-    http.send_request(http_method=requests.get, path="health")
+    with unittest.mock.patch('requests.get') as mock_get:
+        mock_get.return_value.status_code = 200
+        http.send_request(http_method=requests.get, path="health")
 
     assert "Content-Type" not in http.headers
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/client/test_http_requests.py` around lines 33 - 43, The
test_reset_content_type_header test is making an actual HTTP request to the
health endpoint, which creates an external dependency and reduces test
isolation. Mock the requests.get function using unittest.mock.patch before the
http.send_request call to prevent the actual HTTP request from being executed.
This ensures the test remains a pure unit test focused solely on the header side
effect without relying on external services.

33-43: ⚡ Quick win

Add test coverage for post_stream Content-Type cleanup.

Both send_request and post_stream were fixed to remove the Content-Type header when no content_type is provided. Consider adding a parallel test for post_stream to validate the cleanup behavior in both methods.

♻️ Suggested test for post_stream
def test_reset_content_type_header_post_stream():
    """Tests that the content type header is reset in post_stream when content_type=None."""
    config = Config(BASE_URL, MASTER_KEY, timeout=None)
    http = HttpRequests(config=config)

    http.headers["Content-Type"] = "application/json"
    assert http.headers["Content-Type"] == "application/json"

    with unittest.mock.patch('requests.post') as mock_post:
        mock_post.return_value.status_code = 200
        http.post_stream(path="indexes", body={}, content_type=None)

    assert "Content-Type" not in http.headers
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/client/test_http_requests.py` around lines 33 - 43, Add a new test
function to validate that the `post_stream` method properly removes the
Content-Type header when no content_type is provided. Create a test that mirrors
the existing `test_reset_content_type_header` function but calls `post_stream`
instead of `send_request`. The test should set the Content-Type header to a
value, call `post_stream` with `content_type=None`, and then assert that the
Content-Type header has been removed from the http.headers dictionary. Use
unittest.mock.patch to mock the requests.post call to avoid making actual HTTP
requests during testing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/client/test_http_requests.py`:
- Around line 33-43: The test_reset_content_type_header test is making an actual
HTTP request to the health endpoint, which creates an external dependency and
reduces test isolation. Mock the requests.get function using unittest.mock.patch
before the http.send_request call to prevent the actual HTTP request from being
executed. This ensures the test remains a pure unit test focused solely on the
header side effect without relying on external services.
- Around line 33-43: Add a new test function to validate that the `post_stream`
method properly removes the Content-Type header when no content_type is
provided. Create a test that mirrors the existing
`test_reset_content_type_header` function but calls `post_stream` instead of
`send_request`. The test should set the Content-Type header to a value, call
`post_stream` with `content_type=None`, and then assert that the Content-Type
header has been removed from the http.headers dictionary. Use
unittest.mock.patch to mock the requests.post call to avoid making actual HTTP
requests during testing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c77bb851-ca6b-4003-bd94-6325fb1b8a02

📥 Commits

Reviewing files that changed from the base of the PR and between d4d223f and 9fcfb24.

📒 Files selected for processing (2)
  • meilisearch/_httprequests.py
  • tests/client/test_http_requests.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • meilisearch/_httprequests.py

@StephaneRob
StephaneRob force-pushed the fix-reset-content-type branch from 3780318 to bfedff8 Compare June 15, 2026 07:04
@StephaneRob
StephaneRob force-pushed the fix-reset-content-type branch from bfedff8 to fe20386 Compare June 15, 2026 07:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/client/test_http_requests.py (1)

35-46: ⚡ Quick win

Add a companion regression test for post_stream header cleanup.

This test correctly guards send_request, but this PR also changes post_stream. Please add a parallel test to ensure omitted content_type clears stale Content-Type there too, so both modified paths are protected from regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/client/test_http_requests.py` around lines 35 - 46, Add a new
regression test for the `post_stream` method to ensure it clears stale
`Content-Type` headers when no content_type is provided, mirroring the existing
`test_reset_content_type_header` test. Create a test function that follows the
same pattern as `test_reset_content_type_header` (set the Content-Type header,
verify it exists, call `http.post_stream` with appropriate parameters and
without specifying content_type, then assert the header is removed) to ensure
both the `send_request` and `post_stream` code paths are protected from
regression.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/client/test_http_requests.py`:
- Around line 35-46: Add a new regression test for the `post_stream` method to
ensure it clears stale `Content-Type` headers when no content_type is provided,
mirroring the existing `test_reset_content_type_header` test. Create a test
function that follows the same pattern as `test_reset_content_type_header` (set
the Content-Type header, verify it exists, call `http.post_stream` with
appropriate parameters and without specifying content_type, then assert the
header is removed) to ensure both the `send_request` and `post_stream` code
paths are protected from regression.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2d159b94-74a3-423e-af4c-78c44a0173a3

📥 Commits

Reviewing files that changed from the base of the PR and between 9fcfb24 and fe20386.

📒 Files selected for processing (2)
  • meilisearch/_httprequests.py
  • tests/client/test_http_requests.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • meilisearch/_httprequests.py

@StephaneRob
StephaneRob requested a review from Strift June 15, 2026 07:07
@Strift
Strift added this pull request to the merge queue Jun 16, 2026
Merged via the queue into main with commit 624b36e Jun 16, 2026
11 checks passed
@Strift
Strift deleted the fix-reset-content-type branch June 16, 2026 02:33
@Strift Strift changed the title fix: reset content-type when sending request Reset content-type when sending request Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

500 error when deleting temporary index after swap_indexes (Python SDK / remote instance)

2 participants