Describe the bug
I had originally created this ticket to document this issue which was coming from two separate generation errors. The original ticket was closed as completed once one of the two errors was resolved but one still remains. I am opening this specifically for the remaining case.
In the case where there are two swagger components, one referencing another and where the referenced component is marked nullable, the generated code will not have made that class field nullable even though it ought to be.
Here is an example of a component from this spec which references another component called PlaidError.
This component is called Item and can be found on line 43182:
"Item": {
"description": "Metadata about the Item.",
"type": "object",
"additionalProperties": true,
"properties": {
"item_id": {
"description": "The Plaid Item ID. The `item_id` is always unique; linking the same account at the same institution twice will result in two Items with different `item_id` values. Like all Plaid identifiers, the `item_id` is case-sensitive.",
"type": "string"
},
"institution_id": {
"description": "The Plaid Institution ID associated with the Item. Field is `null` for Items created via Same Day Micro-deposits.",
"type": "string",
"nullable": true
},
"webhook": {
"description": "The URL registered to receive webhooks for the Item.",
"type": "string",
"nullable": true
},
"error": {
"$ref": "#/components/schemas/PlaidError"
},
"available_products": {
"description": "A list of products available for the Item that have not yet been accessed. The contents of this array will be mutually exclusive with `billed_products`.",
"type": "array",
"items": {
"$ref": "#/components/schemas/Products"
}
},
"billed_products": {
"description": "A list of products that have been billed for the Item. The contents of this array will be mutually exclusive with `available_products`. Note - `billed_products` is populated in all environments but only requests in Production are billed. Also note that products that are billed on a pay-per-call basis rather than a pay-per-Item basis, such as `balance`, will not appear here.\n",
"type": "array",
"items": {
"$ref": "#/components/schemas/Products"
}
},
"products": {
"description": "A list of authorized products for the Item.\n",
"type": "array",
"items": {
"$ref": "#/components/schemas/Products"
}
},
"consented_products": {
"description": "Beta: A list of products that have gone through consent collection for the Item. Only present for those enabled in the beta.\n",
"type": "array",
"items": {
"$ref": "#/components/schemas/Products"
}
},
"consent_expiration_time": {
"description": "The RFC 3339 timestamp after which the consent provided by the end user will expire. Upon consent expiration, the item will enter the `ITEM_LOGIN_REQUIRED` error state. To circumvent the `ITEM_LOGIN_REQUIRED` error and maintain continuous consent, the end user can reauthenticate via Link’s update mode in advance of the consent expiration time.\n\nNote - This is only relevant for certain OAuth-based institutions. For all other institutions, this field will be null.\n",
"type": "string",
"format": "date-time",
"nullable": true
},
"update_type": {
"type": "string",
"description": "Indicates whether an Item requires user interaction to be updated, which can be the case for Items with some forms of two-factor authentication.\n\n`background` - Item can be updated in the background\n\n`user_present_required` - Item requires user interaction to be updated",
"enum": [
"background",
"user_present_required"
]
}
},
"required": [
"item_id",
"webhook",
"error",
"available_products",
"billed_products",
"consent_expiration_time",
"update_type"
]
},
Notice the reference in the error property of the above component (line 43201 of the swagger file):
If we follow the reference to the appropriate component definition, we find this on line 18570:
"PlaidError": {
"description": "We use standard HTTP response codes for success and failure notifications, and our errors are further classified by `error_type`. In general, 200 HTTP codes correspond to success, 40X codes are for developer- or user-related failures, and 50X codes are for Plaid-related issues. An Item with a non-`null` error object will only be part of an API response when calling `/item/get` to view Item status. Otherwise, error fields will be `null` if no error has occurred; if an error has occurred, an error code will be returned instead.",
"type": "object",
"additionalProperties": true,
"title": "Error",
"nullable": true,
"properties": {
"error_type": {
"$ref": "#/components/schemas/PlaidErrorType"
},
"error_code": {
"description": "The particular error code. Safe for programmatic use.",
"type": "string"
},
"error_message": {
"description": "A developer-friendly representation of the error code. This may change over time and is not safe for programmatic use.",
"type": "string"
},
"display_message": {
"description": "A user-friendly representation of the error code. `null` if the error is not related to user action.\n\nThis may change over time and is not safe for programmatic use.",
"type": "string",
"nullable": true
},
"request_id": {
"type": "string",
"description": "A unique ID identifying the request, to be used for troubleshooting purposes. This field will be omitted in errors provided by webhooks."
},
"causes": {
"type": "array",
"description": "In the Assets product, a request can pertain to more than one Item. If an error is returned for such a request, `causes` will return an array of errors containing a breakdown of these errors on the individual Item level, if any can be identified.\n\n`causes` will only be provided for the `error_type` `ASSET_REPORT_ERROR`. `causes` will also not be populated inside an error nested within a `warning` object.",
"items": {}
},
"status": {
"type": "number",
"description": "The HTTP status code associated with the error. This will only be returned in the response body when the error information is provided via a webhook.",
"nullable": true
},
"documentation_url": {
"type": "string",
"description": "The URL of a Plaid documentation page with more information about the error"
},
"suggested_action": {
"type": "string",
"nullable": true,
"description": "Suggested steps for resolving the error"
}
},
"required": [
"error_type",
"error_code",
"error_message",
"display_message"
]
},
Notice that line 18575 specifies the entire PlaidError component as nullable on any component that references it:
"nullable": true,
Yet when we generate code for the Item component, it looks like this:
Observe that the Item model contains a non-nullable PlaidError field/
Expected behavior
The PlaidError component should be nullable in all generated code since it is marked as nullable in the swagger and this should force it to be nullable anywhere it is referenced.
Describe the bug I had originally created this ticket to document this issue which was coming from two separate generation errors. The original ticket was closed as completed once one of the two errors was resolved but one still remains. I am opening this specifically for the remaining case.
In the case where there are two swagger components, one referencing another and where the referenced component is marked nullable, the generated code will not have made that class field nullable even though it ought to be.
Here is an example of a component from this spec which references another component called
PlaidError
.This component is called
Item
and can be found on line 43182:Notice the reference in the
error
property of the above component (line 43201 of the swagger file):If we follow the reference to the appropriate component definition, we find this on line 18570:
Notice that line 18575 specifies the entire
PlaidError
component as nullable on any component that references it:Yet when we generate code for the
Item
component, it looks like this:Notice this line is not nullable even though it should be:
This would be the correct generated output:
To Reproduce
Item
model contains a non-nullablePlaidError
field/Expected behavior The PlaidError component should be nullable in all generated code since it is marked as nullable in the swagger and this should force it to be nullable anywhere it is referenced.
Swagger specification link https://raw.githubusercontent.com/point-source/dart_plaid/main/swagger/plaid_service.swagger
Library version used: 2.9.0
Additional context This was originally documented here: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/506