[kotlin-client] preserve nullable list item types#23655
[kotlin-client] preserve nullable list item types#23655wing328 merged 1 commit intoOpenAPITools:masterfrom
Conversation
The kotlin-client mustache templates dropped `?` on nullable items
inside List/Array generics. With `items: { type: string, nullable: true }`,
properties now render as `List<kotlin.String?>` instead of
`List<kotlin.String>`, matching kotlin-spring server behavior.
Adds two regression sample configs (jvm-okhttp/moshi and multiplatform/
kotlinx-serialization) plus their generated samples.
There was a problem hiding this comment.
3 issues found across 70 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt">
<violation number="1" location="samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt:8">
P1: ByteArrayAdapter uses raw String/byte conversion with the platform default charset instead of base64, violating OpenAPI `format: byte` wire format and risking data corruption for binary payloads.</violation>
</file>
<file name="samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt">
<violation number="1" location="samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt:128">
P2: `guessContentTypeFromByteArray` may return null despite non-null `String` return type because `URLConnection.guessContentTypeFromStream` can return null without throwing `IOException`. The adjacent `guessContentTypeFromFile` correctly falls back to `"application/octet-stream"`, but this method does not, leading to a runtime null contract violation.</violation>
<violation number="2" location="samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt:164">
P2: Multipart header filtering is case-sensitive, so `content-type` variants can slip through and cause OkHttp to throw when building multipart parts.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| @@ -0,0 +1,12 @@ | |||
| package org.openapitools.client.infrastructure | |||
There was a problem hiding this comment.
P1: ByteArrayAdapter uses raw String/byte conversion with the platform default charset instead of base64, violating OpenAPI format: byte wire format and risking data corruption for binary payloads.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt, line 8:
<comment>ByteArrayAdapter uses raw String/byte conversion with the platform default charset instead of base64, violating OpenAPI `format: byte` wire format and risking data corruption for binary payloads.</comment>
<file context>
@@ -0,0 +1,12 @@
+
+class ByteArrayAdapter {
+ @ToJson
+ fun toJson(data: ByteArray): String = String(data)
+
+ @FromJson
</file context>
| } else { | ||
| "form-data; name=\"$name\"" | ||
| } | ||
| return (headers.filterKeys { it != "Content-Type" } + ("Content-Disposition" to disposition)).toHeaders() |
There was a problem hiding this comment.
P2: Multipart header filtering is case-sensitive, so content-type variants can slip through and cause OkHttp to throw when building multipart parts.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt, line 164:
<comment>Multipart header filtering is case-sensitive, so `content-type` variants can slip through and cause OkHttp to throw when building multipart parts.</comment>
<file context>
@@ -0,0 +1,467 @@
+ } else {
+ "form-data; name=\"$name\""
+ }
+ return (headers.filterKeys { it != "Content-Type" } + ("Content-Disposition" to disposition)).toHeaders()
+ }
+
</file context>
| * @param byteArray The given file | ||
| * @return The guessed Content-Type | ||
| */ | ||
| protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { |
There was a problem hiding this comment.
P2: guessContentTypeFromByteArray may return null despite non-null String return type because URLConnection.guessContentTypeFromStream can return null without throwing IOException. The adjacent guessContentTypeFromFile correctly falls back to "application/octet-stream", but this method does not, leading to a runtime null contract violation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-array-nullable-items/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt, line 128:
<comment>`guessContentTypeFromByteArray` may return null despite non-null `String` return type because `URLConnection.guessContentTypeFromStream` can return null without throwing `IOException`. The adjacent `guessContentTypeFromFile` correctly falls back to `"application/octet-stream"`, but this method does not, leading to a runtime null contract violation.</comment>
<file context>
@@ -0,0 +1,467 @@
+ * @param byteArray The given file
+ * @return The guessed Content-Type
+ */
+ protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String {
+ val contentType = try {
+ URLConnection.guessContentTypeFromStream(byteArray.inputStream())
</file context>
The kotlin-client mustache templates dropped
?on nullable items inside List/Array generics. Withitems: { type: string, nullable: true }, properties now render asList<kotlin.String?>instead ofList<kotlin.String>, matching kotlin-spring server behavior.Adds two regression sample configs (jvm-okhttp/moshi and multiplatform/ kotlinx-serialization) plus their generated samples.
@karismann (2019/03) @Zomzog (2019/04) @andrewemery (2019/10) @4brunu (2019/11) @yutaka0m (2020/03) @stefankoppier (2022/06) @e5l (2024/10) @dennisameling (2026/02)
Summary by cubic
Preserves nullable item types in generated Kotlin client lists/arrays. When an OpenAPI schema sets items.nullable: true, properties now render as
List<kotlin.String?>(orkotlin.Array<kotlin.String?>) instead of non-null elements, matchingkotlin-springserver behavior.kotlin-clientmustache templates (data_class_*_var.mustache,interface_*_var.mustache) to keep item nullability inside generics (e.g.,List<kotlin.String?>).okhttp/moshiand multiplatform withkotlinx-serialization) plus generated samples.Written for commit 800de42. Summary will update on new commits. Review in cubic