Description
When a spec defines a response without a content block (e.g. a 204) alongside a default response with application/json content, the generated Parse*Response function attempts to json.Unmarshal an empty body and returns an error.
The root cause is that getConditionOfResponseName returns "true" for the "default" response name, producing a catch-all case:
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true:
Since the bodyless response has no content definition, GetResponseTypeDefinitions() produces no entry for it, so no guarding case clause is emitted for that status code. When the server returns the bodyless response with a Content-Type header containing "json", the catch-all matches and json.Unmarshal fails with unexpected end of JSON input.
Minimal spec:
openapi: "3.0.0"
info:
title: Repro
version: "1.0"
paths:
/events:
post:
operationId: createEvent
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
responses:
"204":
description: Event received.
"400":
description: Bad request.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
default:
description: Unexpected error.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Error:
type: object
properties:
code:
type: string
message:
type: string
Steps to reproduce
go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen \
-generate models,client -package api spec.yaml > api.gen.go
Then run this test:
func TestParseCreateEventResponse_204_EmptyBody(t *testing.T) {
rsp := &http.Response{
StatusCode: http.StatusNoContent,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(strings.NewReader("")),
}
resp, err := ParseCreateEventResponse(rsp)
if err != nil {
t.Fatalf("expected no error for 204 No Content, got: %v", err)
}
if resp.JSONDefault != nil {
t.Error("expected JSONDefault to be nil for a successful 204")
}
}
Description
When a spec defines a response without a content block (e.g. a 204) alongside a default response with
application/jsoncontent, the generatedParse*Responsefunction attempts tojson.Unmarshalan empty body and returns an error.The root cause is that
getConditionOfResponseNamereturns"true"for the"default"response name, producing a catch-all case:Since the bodyless response has no content definition,
GetResponseTypeDefinitions()produces no entry for it, so no guarding case clause is emitted for that status code. When the server returns the bodyless response with aContent-Typeheader containing"json", the catch-all matches andjson.Unmarshalfails with unexpected end of JSON input.Minimal spec:
Steps to reproduce
go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen \ -generate models,client -package api spec.yaml > api.gen.goThen run this test: