-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
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
- codeGeneration Details
java -jar openapi-generator-cli.jar generate \
-i openapi-bug-repro.yaml \
-g swift6 \
-o ./generatedNo additional configuration options used.
Steps to reproduce
- Save the above OpenAPI spec as
openapi-bug-repro.yaml - Run the generation command above
- Observe the generated
ErrorResponse.swiftfile - 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
isNumericflag which is correctly set
Cons:
- Doesn't address the underlying inconsistency between
dataTypeandisDouble
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
dataTypeandisDoubleconsistent
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!