google/tsunami-security-scanner · error · ValueError
A request body is not allowed for HTTP GET/HEAD request.
Error message
A request body is not allowed for HTTP GET/HEAD request.
What it means
HttpRequest.Builder.build() enforces that GET and HEAD requests carry no body, per the HTTP specification. If a body was set on a GET/HEAD builder, ValueError is raised at build time rather than producing a request that servers would reject or misinterpret.
Solutions
- Change the HTTP method to POST/PUT/PATCH if a body is genuinely required
- Move the data into the URL query string for GET requests (params, not body)
- Skip body assignment when method is GET/HEAD
- Reorder builder calls so the method is set first and gate body-setting on it
Example fix
// before builder.set_method(HttpMethod.GET).set_body(data) return builder.build() # raises // after if data: builder.set_method(HttpMethod.POST).set_body(data) else: builder.set_method(HttpMethod.GET) return builder.build()
Defensive patterns
Strategy: validation
Validate before calling
def build_safe(builder, method, body=None):
if method in (HttpMethod.GET, HttpMethod.HEAD):
body = None
if body:
builder.set_body(body)
builder.set_method(method)
return builder.build() Try / catch
try:
return builder.build()
except ValueError as e:
if 'GET/HEAD' in str(e):
logging.error('Body set on %s request', builder.http_request.method)
raise Prevention
- Set the HTTP method first, then conditionally set the body
- For GET requests put data in the query string, not the body
- Centralize request building in one helper that enforces method/body rules
When it happens
Trigger: Calling set_body(...) (or equivalent) on a builder whose method is GET or HEAD, then calling build(); commonly the method defaults to GET and body-setting code runs unconditionally.
Common situations: Code that always attaches a POST-style JSON body but the method was changed/derived to GET; passing query parameters as a body instead of the URL query string; shared request-building helpers that ignore the method.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Name cannot be None.
- Value cannot be None.
- Illegal header name .
- Illegal header value
- Url cannot be None.
AI-assisted analysis of google/tsunami-security-scanner@363ba87b35 (2026-09-13).
Data as JSON: /api/errors/5caa2366335b3f65.
Report an issue: GitHub.
Appendix: source
Thrown at plugin_server/py/common/net/http/http_request.py:108
return self
def set_request_body(self, request_body: Optional[bytes] = None) -> 'Builder':
"""Set the request body."""
self.http_request.body = request_body
return self
def with_empty_headers(self) -> 'Builder':
"""Set an empty Http_headers for the request."""
self.set_headers(HttpHeadersBuilder().build())
return self
def build(self) -> 'HttpRequest':
if (
self.http_request.method == HttpMethod.GET
or self.http_request.method == HttpMethod.HEAD
):
if self.http_request.body:
raise ValueError(
'A request body is not allowed for HTTP GET/HEAD request.')
return self.http_request
View on GitHub (pinned to 363ba87b35)