Skip to content

Invalid Code Generation for Responses with Content Type "text/plain" #1897

Description

@MrLis

When generating server code using oapi-codegen for an OpenAPI specification that includes responses with the content type "text/plain", the generated code contains invalid type assertions.

Steps to Reproduce:

  1. Create the OpenAPI Specification (spec.yaml):

    openapi: 3.0.3
    info:
      title: Example API
      version: 1.0.0
    
    paths:
      /ping:
        get:
          responses:
            '200':
              $ref: "#/components/responses/200_status_str"
            '201':
              $ref: "#/components/responses/201_status_int"
    
    components:
      responses:
        201_status_int:
          description: status
          content:
            text/plain:
              schema:
                type: integer
        200_status_str:
          description: status
          content:
            text/plain:
              schema:
                type: string
  2. Create the Configuration File (oapi-cfg.yaml):

    # yaml-language-server: $schema=https://raw.githubusercontent.com/deepmap/oapi-codegen/HEAD/configuration-schema.json
    package: main
    output: api.gen.go
    generate:
      models: true
      gorilla-server: true
      strict-server: true
    output-options:
      skip-prune: true
  3. Create main.go:

    package main
    
    import (
    	"context"
    	"fmt"
    	"net/http"
    	"strconv"
    
    	"github.com/gorilla/mux"
    )
    
    type StrictHandler struct{}
    
    func (w StrictHandler) GetPing(ctx context.Context, request GetPingRequestObject) (GetPingResponseObject, error) {
    	return GetPing200TextResponse{
    		N200StatusStrTextResponse(strconv.Itoa(200)),
    	}, nil
    }
    
    func main() {
    	var myHandler StrictHandler
    
    	router := HandlerWithOptions(NewStrictHandler(myHandler, nil), GorillaServerOptions{}).(*mux.Router)
    
    	fmt.Println("Starting server at port 8080")
    	if err := http.ListenAndServe(":8080", router); err != nil {
    		fmt.Println(err)
    	}
    }
  4. Create gen.go:

    package main
    
    //go:generate oapi-codegen --config=oapi-cfg.yaml spec.yaml

Expected Behavior:

The generated code should correctly use GetPing200TextResponse struct:

func (response GetPing200TextResponse) VisitGetPingResponse(w http.ResponseWriter) error {
    w.Header().Set("Content-Type", "text/plain")
    w.WriteHeader(200)

    _, err := w.Write([]byte(response.N200StatusStrTextResponse)) // Correct line
    return err
}

Actual Behavior:

The generated code contains the following invalid line:

func (response GetPing200TextResponse) VisitGetPingResponse(w http.ResponseWriter) error {
    w.Header().Set("Content-Type", "text/plain")
    w.WriteHeader(200)

    _, err := w.Write([]byte(response)) // Invalid line
    return err
}

Handling other types

Generated code for struct GetPing201TextResponse looks the same:

type N201StatusIntTextResponse int

type GetPing201TextResponse struct{ N201StatusIntTextResponse }

func (response GetPing201TextResponse) VisitGetPingResponse(w http.ResponseWriter) error {
	w.Header().Set("Content-Type", "text/plain")
	w.WriteHeader(201)

	_, err := w.Write([]byte(response)) // Invalid line
	return err
}

I expected to see something like this:

_, err := w.Write([]byte(strconv.Itoa(int(response.N201StatusIntTextResponse))))

Additional Information:

  • Version of oapi-codegen: v2.4.1
  • Go Version: 1.22.8
  • Dependencies:
    • github.com/gorilla/mux v1.8.1
    • github.com/oapi-codegen/runtime v1.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions