Skip to content

Nested structs in query params fail to encode #52

Closed as not planned
Closed as not planned

Description

@WarningImHack3r

Such a YAML endpoint fails to encode on client request invocation, leading to a error formatting 'param_id': unsupported type Header error with a nested struct:

...
paths:
  /my/endpoint:
    post:
      security: []
      operationId: myOpId
      parameters:
        - name: param_id
          in: query
          style: form
          schema:
            $ref: "#/components/schemas/ParentStruct"
...

with ParentStruct being generated like:

type ParentStruct struct {
   Header Header `json:"header"` // a simple struct with a few fields
}

(I don't own and can't modify the YAML, I know such a use case is very unconventional)

Call stack:

// my code
client.MyEndpointWithResponse
  // generated code
  c.MyEndpoint(ctx, params, reqEditors...)
    NewMyEndpointRequest(c.Server, params)
      // starting from here we're inside `styleparam.go` from this repo
      runtime.StyleParamWithLocation("form", true, "param_id", runtime.ParamLocationQuery, *params.ParamId)
        styleStruct(style, explode, paramName, paramLocation, value)
          primitiveToString(value) // <-- value is my Header here
            // inside this function, it correctly passes into the `case reflect.Struct`, but fails because it doesn't conform to `uuid.UUID` nor to `json.Marshaler` (for some reason)
            // as a result, it `fallthrough`s in `default:` and also fails the conformity check to `fmt.Stringer`, leading to the error.

I didn't inspect the code that much, but I fail to understand why the serialization process uses the custom reflection logic instead of simply using json.Encode which would 100% do the job.

Thank you in advance!

Activity

  1. mromaszewicz commented on Jul 12, 2026

    @mromaszewicz
    Member

    That spec isn't valid OpenAPI. I realize you don't control it, but I really don't know what to do for undefined behavior. OpenAPI says that form parameters are simple types or flat objects, not nested objects, so we don't have code to detect this case.

    If I assume some behavior, it will likely be wrong for some server, or some client, because being undefined, anyone can do what they want.

    In this particular case, you could either edit the spec to use a Content-Type based parameter (like application/json) and marshal it as JSON, or you add a helper file alongside the generated code where you define fmt.Stringer for the generated model for param_id which converts it to a string.

    I really can't fix this generically, so what I'll be doing is throwing a more meaningful error.

  2. WarningImHack3r commented on Jul 12, 2026

    @WarningImHack3r
    Author

    Oh, I didn't know that: thanks for the info and the explicit error!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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