fix(http-provider): don't double-encode a templated JSON body - #6688
Open
dngr2 wants to merge 1 commit into
Open
fix(http-provider): don't double-encode a templated JSON body#6688dngr2 wants to merge 1 commit into
dngr2 wants to merge 1 commit into
Conversation
_query() normalised `headers` when they arrived as a string but never did
the same for `body`. A workflow using `body: "{{ alert }}"` renders to a
JSON string, which was then passed to requests as `json=body` and
serialised a second time, so the endpoint received a quoted string rather
than an object.
Parse a string body before sending, mirroring the existing `headers`
handling three lines above. Only an object or array is accepted: json.loads
("123") succeeds and returns an int, and a bare scalar was almost certainly
meant as a plain-text body. A body that is still a string afterwards goes
out as `data=` with the caller's Content-Type, since `json=` would
re-serialise it.
Note this is a behaviour change for anyone currently sending a JSON string
and compensating for the double encoding downstream. The current behaviour
contradicts both the documented Content-Type and the handling of `headers`
in the same function, so it looks like the bug rather than the contract.
Adds tests for templated and nested JSON strings on POST/PUT/DELETE, plain
text and XML bodies going out as data, a bare numeric string not being
treated as JSON, and regression guards for dict, list and None bodies.
Fixes keephq#6547
dngr2
force-pushed
the
fix/6547-http-provider-json-body
branch
from
August 12, 2026 02:51
c11b56b to
5ad6f1f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6547
The bug
_query()normalisesheaderswhen they arrive as a string:but never does the same for
body, which is then handed to requests asjson=body. A workflow using a templated body renders to a JSON string:json=serialises it a second time, so the endpoint receives a quoted string instead of an object — with aContent-Type: application/jsonheader that no longer describes the payload.The fix
Parse a string body before sending, mirroring the
headershandling three lines above.Two details worth flagging for review:
json.loads("123")does not raise — it returns an int. Converting a body of"123"into a number would be a silent change, so a bare scalar is left as text.ValueErrorcatch is deliberate. This module importsJSONDecodeErrorfromrequests.exceptions, which is a subclass of the onejson.loadsraises, so catching it would not work here.A body that is still a string afterwards goes out as
data=with the caller'sContent-Type, sincejson=would re-serialise it.Behaviour change
This changes what reaches the endpoint for anyone currently sending a JSON string and compensating for the double encoding downstream. I believe the current behaviour is the bug rather than the contract, since it contradicts both the declared
Content-Typeand the handling ofheadersin the same function — but flagging it explicitly since it is the kind of thing that can bite silently.Tests
New file:
tests/providers/http_provider/test_http_provider_json_body.pyWritten before the fix and run against unmodified
main: 7 failed, 5 passed. With the fix: 12 passed. The 5 that passed throughout are the regression guards, which is the point of them.data, not JSON-encodedNonebodies unchangedtests/providersin full: 65 passed. I have not run the suites needing Docker and a database locally — leaving those to CI.Touches the same file as #6687 but different lines; whichever lands first, I am happy to rebase the other.