grpc-ecosystem/grpc-gateway · error
must not set request body when http method is DELETE except
Error message
must not set request body when http method is DELETE except allow_delete_body option is true: %s
What it means
DELETE with a request body is discouraged and not supported by default; the generator only allows a 'body' on a 'delete' rule when the allow_delete_body option is explicitly enabled. Otherwise template building fails with the method descriptor name.
Source
Thrown at internal/descriptor/services.go:123
httpMethod = "GET"
pathTemplate = opts.GetGet()
if opts.Body != "" {
return nil, fmt.Errorf("must not set request body when http method is GET: %s", md.GetName())
}
case opts.GetPut() != "":
httpMethod = "PUT"
pathTemplate = opts.GetPut()
case opts.GetPost() != "":
httpMethod = "POST"
pathTemplate = opts.GetPost()
case opts.GetDelete() != "":
httpMethod = "DELETE"
pathTemplate = opts.GetDelete()
if opts.Body != "" && !r.allowDeleteBody {
return nil, fmt.Errorf("must not set request body when http method is DELETE except allow_delete_body option is true: %s", md.GetName())
}
case opts.GetPatch() != "":
httpMethod = "PATCH"
pathTemplate = opts.GetPatch()
case opts.GetCustom() != nil:
custom := opts.GetCustom()
httpMethod = custom.Kind
pathTemplate = custom.Path
default:
if grpclog.V(1) {
grpclog.Infof("No pattern specified in google.api.HttpRule: %s", md.GetName())
}
return nil, nil
}
View on GitHub (pinned to a58a4436a3)
Solutions
- Remove the 'body' field from the DELETE annotation and pass identifiers via the path template
- If a body is genuinely required, enable the allow_delete_body generator option
- Replace the rpc with a POST-based bulk action (e.g. '/v1/items:batchDelete')
- Align the annotation with REST conventions: DELETE targets identified by path
Example fix
// before
option (google.api.http) = { delete: "/v1/items" body: "*" };
// after
option (google.api.http) = { post: "/v1/items:batchDelete" body: "*" }; Defensive patterns
Strategy: validation
Validate before calling
if rule.GetDelete() != "" && rule.GetBody() != "" && !allowDeleteBody {
return fmt.Errorf("rpc %s: DELETE with body requires allow_delete_body", rpc.GetName())
}
err := buildTemplates(rpc) Prevention
- Prefer path-parameter-based DELETE; reserve bodies for POST bulk endpoints
- If you must send a DELETE body, explicitly enable allow_delete_body in your generation flags and document why
- Add a lint rule rejecting 'delete' annotations containing 'body'
When it happens
Trigger: A rpc's google.api.http option sets both 'delete' and a non-empty 'body', while Registry.allowDeleteBody is false (the default, set via CLI flag).
Common situations: Copy-pasting a POST annotation and changing only the verb to delete; bulk-delete rpcs that want a body; teams unaware that the generator requires an opt-in flag for this nonstandard pattern.
Related errors
- must not set request body when http method is GET: %s
- duplicate annotation: method=%s, template=%s
- no target service defined in the file
- only primitive and enum types are allowed in repeated path p
- only primitive and well-known types are allowed in path para
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/c7c6cd8ff06b73fe.
Report an issue: GitHub.