Skip to content

[BUG][Swift6] Number enum without format incorrectly conforms to ParameterConvertible #22624

@berk-dilek

Description

@berk-dilek

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

When generating Swift6 code for an enum property with type: number (without an explicit format), the generated enum incorrectly conforms to ParameterConvertible. This causes a Swift compilation error because the enum already receives the asParameter method via the RawRepresentable extension defined in Extensions.swift.

Interestingly, this issue does not occur with type: integer enums, which generate correctly without the ParameterConvertible conformance.

The current workaround is to set the parameterConvertible option to false or change the data type to integer. Ideally, the tool should produce a working Swift6 package with or without this flag for a valid spec.

openapi-generator version

Reproduced on:

  • Latest stable release (installed via Homebrew/npm)
  • Latest master (7.19.0-SNAPSHOT, built from source as of January 5, 2026)

This confirms the issue exists in both the current release and the latest development version.

OpenAPI declaration file content or url

Minimal reproduction spec:

openapi: 3.0.3
info:
  title: Minimal Bug Reproduction - Swift6 ParameterConvertible Issue
  version: 1.0.0

paths:
  /example:
    get:
      operationId: getExample
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExampleResponse'
        '400':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  schemas:
    ExampleResponse:
      type: object
      properties:
        message:
          type: string
      required:
        - message

    ErrorResponse:
      type: object
      properties:
        id:
          type: string
        message:
          type: string
        code:
          type: number
          enum:
            - 601
      required:
        - id
        - message
        - code

Generation Details

java -jar openapi-generator-cli.jar generate \
  -i openapi-bug-repro.yaml \
  -g swift6 \
  -o ./generated

No additional configuration options used.

Steps to reproduce

  1. Save the above OpenAPI spec as openapi-bug-repro.yaml
  2. Run the generation command above
  3. Observe the generated ErrorResponse.swift file
  4. Try to compile the generated Swift package

Actual Output

public enum Code: Double, Sendable, Codable, ParameterConvertible, CaseIterable {
    case _601 = 601
}

This fails to compile with the error:

Type 'ErrorResponse.Code' does not conform to protocol 'ParameterConvertible'

Why this error occurs

The ParameterConvertible protocol requires implementing asParameter(codableHelper:). The generated code expects this method to come from the RawRepresentable extension in Extensions.swift:

extension RawRepresentable where RawValue: ParameterConvertible, RawValue: Sendable {
    func asParameter(codableHelper: CodableHelper) -> any Sendable { return self.rawValue }
}

However, this extension provides the method conditionally (via protocol extension), not as a direct conformance. When the enum explicitly declares ParameterConvertible conformance in its declaration, Swift requires the type to directly satisfy the protocol—the conditional extension method doesn't count.

For type: integer enums (which work correctly), ParameterConvertible is not added to the declaration, so the enum naturally gets asParameter through the RawRepresentable extension without any issues.

Expected Output

public enum Code: Double, Sendable, Codable, CaseIterable {
    case _601 = 601
}

Without ParameterConvertible conformance (same behavior as type: integer enums).

Related issues/PRs

I searched but did not find an existing issue for this specific problem.

Root Cause Analysis

The issue is in the mustache templates (modelEnum.mustache and modelInlineEnumDeclaration.mustache). The current logic for adding ParameterConvertible:

{{^isString}}{{^isInteger}}{{^isFloat}}{{^isDouble}}{{#useParameterConvertible}}, ParameterConvertible{{/useParameterConvertible}}{{/isDouble}}{{/isFloat}}{{/isInteger}}{{/isString}}

This checks isDouble, but isDouble is only set to true when format: double is explicitly specified. For type: number without a format:

Flag Value
dataType Double
isDouble false ✗ (only true if format: double)
isNumeric true

So the condition passes incorrectly, adding ParameterConvertible.

Suggest a fix

I've prepared two potential fixes and would appreciate the team's guidance on which approach is preferred:

Option 1: Template Fix (Swift6-specific)

Draft PR: #22622

Add {{^isNumeric}} check to the templates:

{{^isString}}{{^isInteger}}{{^isFloat}}{{^isDouble}}{{^isNumeric}}{{#useParameterConvertible}}, ParameterConvertible{{/useParameterConvertible}}{{/isNumeric}}{{/isDouble}}{{/isFloat}}{{/isInteger}}{{/isString}}

Pros:

  • Localized fix, only affects Swift6
  • Lower risk of unintended side effects
  • Uses existing isNumeric flag which is correctly set

Cons:

  • Doesn't address the underlying inconsistency between dataType and isDouble

Option 2: Core Fix (DefaultCodegen.java)

Draft PR: #22623

Modify updateModelForNumber and updatePropertyForNumber in DefaultCodegen.java to set isDouble = true for all number types that aren't explicitly float:

protected void updatePropertyForNumber(CodegenProperty property, Schema p) {
    property.isNumeric = Boolean.TRUE;
    if (ModelUtils.isFloatSchema(p)) {
        property.isFloat = Boolean.TRUE;
    } else {
        // Set isDouble for explicit "format: double" OR when no format is specified
        property.isDouble = Boolean.TRUE;
    }
}

Pros:

  • Fixes the root cause
  • Benefits all generators that rely on isDouble
  • Makes dataType and isDouble consistent

Cons:

  • Changes core behavior affecting all languages
  • Higher risk of unintended side effects in other generators

I'm happy to proceed with either approach based on the team's preference, or implement an alternative solution if suggested. Please let me know if additional information would be helpful!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions