Skip to content

Memory leak while using huma.MultipartFormFiles[T] #902

@TimurUtyaganov

Description

@TimurUtyaganov

Describe the bug

When parsing multipart/form-data request in this method
findParams(registry Registry, op *Operation, t reflect.Type) *findResult[*paramFieldInfo]
huma write same parameters to op.Parameters slice without releasing memory which causes OOM error.

Steps to Test or Reproduce

My input

type StoreByFormInput struct {
	Driver  string `path:"driver"`
	RawBody huma.MultipartFormFiles[request.StoreFile]
	RealIP  string
}
type StoreFile struct {
	File      huma.FormFile `form:"file" required:"true"`
	Tags      []string      `form:"tags" required:"false"`
	TTL       uint64        `form:"ttl" required:"false"`
	Latitude  float64       `form:"latitude" required:"false"`
	Longitude float64       `form:"longitude" required:"false"`
}

With every file upload huma tries to find parameters in form and then writes them to op.Parameters in this code block

if !boolTag(f, "hidden", false) {
			desc := ""
			if pfi.Schema != nil {
				// If the schema has a description, use it. Some tools will not show
				// the description if it is only on the schema.
				desc = pfi.Schema.Description
			}

			// Document the parameter if not hidden.
			op.Parameters = append(op.Parameters, &Param{
				Name:        name,
				Description: desc,
				In:          pfi.Loc,
				Explode:     explode,
				Required:    pfi.Required,
				Schema:      pfi.Schema,
				Example:     example,
				Style:       pfi.Style,
			})
		}

If we have thousands of requests, the slice grows to hundreds of mb and we get OOM error. The problem has workaround if we make all params hidden, but it's not perfect of course.

Expected behavior

Make a map maybe? Or check if param already exists by its name. I can make a PR if you want

##Screenshots
Below is a picture from pyroscope where memory is gradually increasing

Dependency versions

The version of are you using for:
huma version v2.34.1

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions