Bug Report Checklist
Description
The change introduced in #17267 added a call to DisallowUnknownFields() on the Go JSON decoder to reject unknown fields. This unintentionally broke JSON unmarshalling in generated code that uses Go struct embedding.
Why? When using struct embedding, the embedded struct's UnmarshalJSON(data []byte) error method receives the full JSON object, including fields from its parent. Due to DisallowUnknownFields(), any unknown parent fields will cause unmarshalling to fail.
In the case of the Go generator, I found that the issue occurs when using discriminators. See the steps to reproduce below.
I'm very surprised that this critical bug has remained unnoticed for over a year.
openapi-generator version
v7.12.0
Steps to reproduce
Use the spec file:
modules/openapi-generator/src/test/resources/3_0/go/allof_multiple_ref_and_discriminator.yaml
and the corresponding generated code:
samples/client/others/go/allof_multiple_ref_and_discriminator.
To reproduce the issue:
- Add a new test file
issue_test.go in samples/client/others/go/allof_multiple_ref_and_discriminator with the following content:
package openapi
import (
"encoding/json"
"fmt"
"testing"
)
func TestUnmarshalFinalItem(t *testing.T) {
jsonStr := `{
"prop1": "example",
"quantity": 10,
"unitPrice": 5.5,
"totalPrice": 55.0,
"title": "example",
"type": "FINAL"
}`
var item FinalItem
err := json.Unmarshal([]byte(jsonStr), &item)
if err != nil {
t.Fatalf("Unmarshal error: %v", err)
}
fmt.Printf("Unmarshalled FinalItem: %+v\n", item)
}
- Run the tests with:
You will observe the following error:
--- FAIL: TestUnmarshalFinalItem (0.00s)
issue_test.go:22: Unmarshal error: json: unknown field "prop1"
The error is caused by the DisallowUnknownFields() inside the embedded struct UnmarshalJSON(data []byte) (err error) function:
https://github.com/curvegrid/openapi-generator/blob/afc27ef4bc969f07613807aba51ec1a9f46cf605/samples/client/others/go/allof_multiple_ref_and_discriminator/model_base_item.go#L138
Suggest a fix
It is not because additionalProperties is set to false in the OpenAPI spec that a generated client should completely fail if the server returns extra fields. In real-world APIs, it is common for servers to evolve and add new properties over time.
The use of DisallowUnknownFields() in generated client code is extremely dangerous because:
- It prevents clients from tolerating new fields added to the server response, making clients extremely fragile.
- It breaks backward compatibility: older clients interacting with newer servers will crash when they encounter unexpected fields.
- It fundamentally contradicts robust client design principles, where clients should ignore unknown fields rather than fail.
I would propose to remove DisallowUnknownFields() from the Go client templates as soon as possible to restore proper resilience and compatibility when dealing with evolving APIs (and embedded structs).
Bug Report Checklist
Description
The change introduced in #17267 added a call to
DisallowUnknownFields()on the Go JSON decoder to reject unknown fields. This unintentionally broke JSON unmarshalling in generated code that uses Go struct embedding.Why? When using struct embedding, the embedded struct's
UnmarshalJSON(data []byte) errormethod receives the full JSON object, including fields from its parent. Due toDisallowUnknownFields(), any unknown parent fields will cause unmarshalling to fail.In the case of the Go generator, I found that the issue occurs when using discriminators. See the steps to reproduce below.
I'm very surprised that this critical bug has remained unnoticed for over a year.
openapi-generator version
v7.12.0
Steps to reproduce
Use the spec file:
modules/openapi-generator/src/test/resources/3_0/go/allof_multiple_ref_and_discriminator.yamland the corresponding generated code:
samples/client/others/go/allof_multiple_ref_and_discriminator.To reproduce the issue:
issue_test.goinsamples/client/others/go/allof_multiple_ref_and_discriminatorwith the following content:go testYou will observe the following error:
The error is caused by the
DisallowUnknownFields()inside the embedded structUnmarshalJSON(data []byte) (err error)function:https://github.com/curvegrid/openapi-generator/blob/afc27ef4bc969f07613807aba51ec1a9f46cf605/samples/client/others/go/allof_multiple_ref_and_discriminator/model_base_item.go#L138
Suggest a fix
It is not because
additionalPropertiesis set tofalsein the OpenAPI spec that a generated client should completely fail if the server returns extra fields. In real-world APIs, it is common for servers to evolve and add new properties over time.The use of
DisallowUnknownFields()in generated client code is extremely dangerous because:I would propose to remove
DisallowUnknownFields()from the Go client templates as soon as possible to restore proper resilience and compatibility when dealing with evolving APIs (and embedded structs).