-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
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.goinsamples/client/others/go/allof_multiple_ref_and_discriminatorwith 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:
go testYou 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).