Version
@azure/functions: reproduced on 4.16.0, 4.16.1, and 4.16.2
- Node.js: production Node 20; also reproduced locally on Node 24
- Azure Functions Core Tools: 4.8.0
- Hosting: Azure Static Web Apps managed Functions
Reproduction
const { HttpRequest } = require('@azure/functions');
new HttpRequest({
url: 'https://example.test/api/probe',
method: 'GET',
body: { string: 'x' },
});
This throws before an application handler can run:
TypeError: Request with GET/HEAD method cannot have body.
at new Request (node:internal/deps/undici/undici:10023:17)
at new HttpRequest (@azure/functions/dist/azure-functions.js:2136:25)
at fromRpcTypedData
at InvocationModel.getArguments
The public SWA behavior was also deterministic before applying an application workaround:
curl -X GET --data x https://red-river-0f7efed00.7.azurestaticapps.net/api/health/bootstrap
A GET with a body returned a bare 500 and never reached the handler. The same request with no body or Content-Length: 0 reached the handler and returned its expected 401 JSON auth response.
Cause
In 4.16.x, the non-streaming RPC HttpRequest constructor passes the decoded RPC body to the global WHATWG Request for every method. The streaming createStreamRequest path already omits the body for GET and HEAD. The two paths therefore behave differently.
Organic body provenance is unknown because the available telemetry does not retain request headers/body length or client identity. Possible sources include malformed external traffic or an upstream host/proxy handoff; this report only claims the deterministic library failure once RPC data contains a GET/HEAD body.
Expected behavior
The RPC path should match the streaming path and omit body for GET and HEAD before constructing the WHATWG Request. A regression test should cover GET/HEAD bodies (including zero-length RPC bodies), mixed-case methods if accepted internally, and preservation of POST/PUT/PATCH bodies.
Version
@azure/functions: reproduced on 4.16.0, 4.16.1, and 4.16.2Reproduction
This throws before an application handler can run:
The public SWA behavior was also deterministic before applying an application workaround:
A GET with a body returned a bare 500 and never reached the handler. The same request with no body or
Content-Length: 0reached the handler and returned its expected 401 JSON auth response.Cause
In 4.16.x, the non-streaming RPC
HttpRequestconstructor passes the decoded RPC body to the global WHATWGRequestfor every method. The streamingcreateStreamRequestpath already omits the body for GET and HEAD. The two paths therefore behave differently.Organic body provenance is unknown because the available telemetry does not retain request headers/body length or client identity. Possible sources include malformed external traffic or an upstream host/proxy handoff; this report only claims the deterministic library failure once RPC data contains a GET/HEAD body.
Expected behavior
The RPC path should match the streaming path and omit
bodyfor GET and HEAD before constructing the WHATWGRequest. A regression test should cover GET/HEAD bodies (including zero-length RPC bodies), mixed-case methods if accepted internally, and preservation of POST/PUT/PATCH bodies.