[BUG][KOTLIN] jvm-retrofit2: DELETE with requestBody fails with "Non-body HTTP method cannot contain @Body"
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 80/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
調査の方向性
issue によると Retrofit アノテーションが生成される kotlin-client/libraries/jvm-retrofit2/api.mustache から始め、このライブラリの近くにあるテンプレートテストを調べてください。リンクされた最小仕様で再現し、リクエストボディを持つ DELETE 操作によって、JSON ボディを送信する呼び出し可能なクライアントメソッドが生成されることを確認してください。issue では、関連するテンプレートとして Java/libraries/retrofit2/api.mustache も確認するよう示されています。
索引モデルが issue の本文から書いたものです。
説明
[!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.
- 主要言語
- Java
- スター
- 26.8k
- フォーク
- 7.7k
- 平均マージ
- 1日 14時間
- マージ済み PR(30日)
- 185
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
OpenAPITools/openapi-generator のほかの issue
-
Issue: Bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
OpenAPITools/openapi-generator#25475 ·
メンテナーはふだん 1 日以内に返信
-
Enhancement: Feature
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
OpenAPITools/openapi-generator#25425 ·
メンテナーはふだん 1 日以内に返信
-
[REQ][JAVA][resteasy] Support for Jackson 3 / useJackson3対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンEnhancement: Feature
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
OpenAPITools/openapi-generator#25364 ·
メンテナーはふだん 1 日以内に返信
-
[BUG][RUST] chrono date-time path/query/header params are not serialized as RFC 3339対応中かも @teovillanueva が 13 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
OpenAPITools/openapi-generator#25297 ·
メンテナーはふだん 1 日以内に返信
-
[BUG][RUST] Reqwest - encoding of spaces in path parameters対応中かも @GlenWright が 16 日前に担当しました。 オープンIssue: Bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
OpenAPITools/openapi-generator#25257 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
OpenAPITools/openapi-generator の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
bug/错误
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
FCL-Team/FoldCraftLauncher#1982 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
[BUG] micronaut-serde-oracle-jdbc-json brings a second OJDBC driver onto the runtime classpath対応中かも @ZARAYACH が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
micronaut-projects/micronaut-serialization#1494 · コメント 4 件 ·
メンテナーはふだん 2 日以内に返信
-
難易度 1/5 1〜3時間 初心者へのやさしさ 75/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
メンテナーはふだん 2 日以内に返信