OpenAPITools / OpenAPITools/openapi-generator

[BUG][kotlin][jvm-retrofit2] Invalid default value for enum array parameter with $ref

Open
#14,873 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • 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?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

Given an API spec with query parameters,
and a parameter is an array of enum with a default value,
When generating a client in Kotlin with library=jvm-retrofit2,

  • Expected: parameter/property someEnumArray: List<SomeEnum>? = arrayListOf(SomeEnum.foo)
  • Actual: parameter/property someEnumArray: List<SomeEnum>? = arrayListOf(null), which isn't the default value from the spec and is invalid, since the list item type isn't nullable, causing compilation to fail.

The query parameters, which are by default exploded, have an invalid default value in the Api class:

interface DefaultApi {
    fun getSomeValue(@Query("someEnumArray") someEnumArray: List<SomeEnum>? = arrayListOf(null)): Call<Unit>

And in the query object, which isn't used but will fail to compile:

data class SomeQuery (
    @Json(name = "someEnumArray")
    val someEnumArray: List<SomeEnum>? = arrayListOf(null)
)

In the latest master (https://github.com/OpenAPITools/openapi-generator/commit/c8fab3f40a1b00db75d61716016ed0846de65c42), the invalid default value is only reported for SomeQuery. Compilation of DefaultApi fails earlier because of #14871.

> Task :compileKotlin FAILED
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt: (22, 85): Unresolved reference: SomeEnum
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/models/SomeQuery.kt: (32, 61): Type mismatch: inferred type is SomeEnum? but SomeEnum was expected
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/models/SomeQuery.kt: (32, 61): Type mismatch: inferred type is kotlin.collections.ArrayList<Nothing?> /* = java.util.ArrayList<Nothing?> */ but List<SomeEnum>? was expected

After applying the suggested fix of #14871, exploded enum parameter arrays without default values will compile, but with default values there's still an issue:

> Task :compileKotlin FAILED
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt: (23, 98): Type mismatch: inferred type is SomeEnum? but SomeEnum was expected
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt: (23, 98): Type mismatch: inferred type is kotlin.collections.ArrayList<Nothing?> /* = java.util.ArrayList<Nothing?> */ but List<SomeEnum>? was expected
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/models/SomeQuery.kt: (32, 61): Type mismatch: inferred type is SomeEnum? but SomeEnum was expected
e: /Users/gabrielfeo2/projects/openapi-generator/out/src/main/kotlin/org/openapitools/client/models/SomeQuery.kt: (32, 61): Type mismatch: inferred type is kotlin.collections.ArrayList<Nothing?> /* = java.util.ArrayList<Nothing?> */ but List<SomeEnum>? was expected
openapi-generator version

Occurs in v6.4.0 and master (c8fab3f4).

OpenAPI declaration file content or url
Expand yaml
openapi: 3.0.3
info:
  title: Issue 11242 - exploded query params
  description: "Exploded query params"
  version: "1.0.0"
servers:
  - url: localhost:8080
paths:
  /api:
    get:
      operationId: GetSomeValue
      parameters:
        - in: query
          name: QueryObject
          schema:
            properties:
              someEnumArray:
                type: array
                items:
                  $ref: '#/components/schemas/SomeEnum'
                default:
                  - foo
      responses:
        '204':
          description: Success
components:
  schemas:
    SomeEnum:
      type: string
      enum:
        - foo
        - bar
Generation Details
openapi-generator generate -g kotlin -p library=jvm-retrofit2
Steps to reproduce
  1. Generate a client project using above options and spec
  2. In the project directory, run ./gradlew compileKotlin
Related issues/PRs
  • #13154 originally implemented exploding for this generator+library, but
  • #14871 also about exploded parameters, but while this issue only affects schemas with default values for enums, that issue affects any schema with exploded enums. After that one's fixed, this one remains an issue, but for a subset of cases.
Suggest a fix

I believe the issue lies around AbstractKotlinCodegen.toDefaultValue and detecting from which schema the default value comes from. I'd be happy to contribute with a PR, but I'd need some guidance about how default-value parsing is implemented.

Also, this could be helpful for debugging: if we don't specify that the enum is a separate $ref (and a separate class), then default values are generated correctly:

Expand yaml without $ref
openapi: 3.0.3
info:
  title: Issue 11242 - exploded query params
  description: "Exploded query params"
  version: "1.0.0"
servers:
  - url: localhost:8080
paths:
  /api:
    get:
      operationId: GetSomeValue
      parameters:
        - in: query
          name: QueryObject
          explode: false
          schema:
            properties:
              someEnumArray:
                type: array
                items:
                  type: string
                  enum:
                    - foo
                    - bar
                default:
                  - foo
      responses:
        '204':
          description: Success

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with AbstractKotlinCodegen.toDefaultValue, which the issue identifies as the likely entry point. Reproduce the case using the supplied OpenAPI YAML and openapi-generator generate -g kotlin -p library=jvm-retrofit2, then run ./gradlew compileKotlin. Done means the generated enum-array defaults use the specified enum value instead of null and compile successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kotlin
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.