[BUG][KOTLIN] jvm-retrofit2: DELETE with requestBody fails with "Non-body HTTP method cannot contain @Body"
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 80/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- backend-api-design, tooling
Research direction
Start with kotlin-client/libraries/jvm-retrofit2/api.mustache, where the issue says Retrofit annotations are generated, and inspect nearby template tests for this library. Reproduce with the linked minimal spec and confirm a DELETE operation with a request body generates a callable client method that sends the JSON body. The issue also points to Java/libraries/retrofit2/api.mustache as a related template to check.
Written by the indexing model from the issue text.
Description
[!NOTE]
🤖 Claude Opus 5.5 opening this issue on behalf of Will
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
Description
With generatorName = kotlin and library = jvm-retrofit2, a DELETE operation that has a requestBody generates @DELETE("path") plus an @Body parameter. It compiles, but Retrofit rejects the method on the first call:
java.lang.IllegalArgumentException: Non-body HTTP method cannot contain @Body.
for method DefaultApi.deleteItems
at retrofit2.Utils.methodError(Utils.java:56)
at retrofit2.Utils.methodError(Utils.java:44)
at retrofit2.RequestFactory$Builder.build(RequestFactory.java:220)
at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:67)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:26)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:235)
at retrofit2.Retrofit$1.invoke(Retrofit.java:177)
OpenAPI 3 allows a body on DELETE, so the generated client can't call these operations at all. We hit it on every call to a DELETE endpoint with a required JSON body in our app.
Minimal repro: https://github.com/ceolinwill/openapi-kotlin-retrofit-delete-body-repro
openapi-generator version
7.26.0 (latest release), Gradle plugin. Not a regression as far as I can tell: the template line is the same on master.
OpenAPI declaration file content or url
openapi: 3.0.3
info:
title: Repro
version: 1.0.0
paths:
/items:
delete:
operationId: deleteItems
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/DeleteItemsRequest"
responses:
"204":
description: Deleted
components:
schemas:
DeleteItemsRequest:
type: object
required: [ids]
properties:
ids:
type: array
items:
type: string
openApiValidate reports "Spec is valid."
Generation Details
openApiGenerate {
generatorName = "kotlin"
library = "jvm-retrofit2"
inputSpec = layout.projectDirectory.file("openapi.yaml")
outputDir = layout.buildDirectory.dir("generated")
packageName = "repro.client"
configOptions = mapOf(
"serializationLibrary" to "kotlinx_serialization",
"useCoroutines" to "true",
)
}
Generated:
@DELETE("items")
suspend fun deleteItems(@Body deleteItemsRequest: DeleteItemsRequest): Response<Unit>
Retrofit 3.0.0, OkHttp 5.5.1, Kotlin 2.4.21, JDK 17.
Steps to reproduce
git clone https://github.com/ceolinwill/openapi-kotlin-retrofit-delete-body-repro && cd openapi-kotlin-retrofit-delete-body-repro./gradlew run -q: callsdeleteItemsagainst MockWebServer and throws the exception above../gradlew run -q -PwithFix: same code generated with the template change below. PrintsDELETE /items {"ids":["a","b"]}.
Expected: the request is sent as DELETE /items with the JSON body.
Actual: IllegalArgumentException before any request is made.
Related issues/PRs
I found none for Kotlin or Retrofit. #7557 / #7558 were the same kind of problem in typescript-angular.
Suggest a fix
kotlin-client/libraries/jvm-retrofit2/api.mustache always emits @{{httpMethod}}("{{{path}}}") (line 158). Retrofit's documented way to send a body with a method that has no body by default is @HTTP(method = ..., path = ..., hasBody = true). Changing that line to this fixes it in the repro, and leaves operations without a body unchanged:
{{#bodyParam}}@HTTP(method = "{{httpMethod}}", path = "{{{path}}}", hasBody = true){{/bodyParam}}{{^bodyParam}}@{{httpMethod}}("{{{path}}}"){{/bodyParam}}
retrofit2.http.* is already imported. Java/libraries/retrofit2/api.mustache has the same @{{httpMethod}}("{{{path}}}") line, so the Java retrofit2 client likely has the same problem; I haven't run it.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 187
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from OpenAPITools/openapi-generator
-
Enhancement: Feature
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
OpenAPITools/openapi-generator#25425 ·
Maintainers usually reply within 1 day
-
[REQ][JAVA][resteasy] Support for Jackson 3 / useJackson3Possibly taken A pull request linked to this issue is open or already merged. OpenEnhancement: Feature
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
OpenAPITools/openapi-generator#25364 ·
Maintainers usually reply within 1 day
-
[BUG][RUST] chrono date-time path/query/header params are not serialized as RFC 3339Possibly taken @teovillanueva claimed this 11 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
OpenAPITools/openapi-generator#25297 ·
Maintainers usually reply within 1 day
-
[BUG][RUST] Reqwest - encoding of spaces in path parametersPossibly taken @GlenWright claimed this 14 days ago. OpenIssue: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
OpenAPITools/openapi-generator#25257 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
OpenAPITools/openapi-generator#25237 ·
Maintainers usually reply within 1 day
All issues in OpenAPITools/openapi-generator
Similar issues
-
priority: medium Review effort [1-5]: 3 status: needs-triage type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
carlos-emr/carlos#5431 ·
Maintainers usually reply within 1 day
-
Integration tests: jetty:run fails with WELD-001408 for CountryJpaServicePossibly taken @viniciusmachak claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
primefaces/primefaces#15431 ·
Maintainers usually reply within 1 day
-
Component - Build
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
navikt/mock-oauth2-server#1149 ·
Maintainers usually reply within 1 day