Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions huma.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,11 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I)
return
}

// Skip FormFile and []FormFile fields - they are handled separately
if p.Type.String() == "huma.FormFile" || p.Type.String() == "[]huma.FormFile" {
return
}

pb.Reset()
pb.Push(p.Loc)
pb.Push(p.Name)
Expand Down
32 changes: 32 additions & 0 deletions huma_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,38 @@ Hello, World!
assert.Equal(t, http.StatusUnprocessableEntity, resp.Code)
},
},
{
Name: "request-body-multipart-file-decoded-text-value-sent-to-file-field",
Register: func(t *testing.T, api huma.API) {
huma.Register(api, huma.Operation{
Method: http.MethodPost,
Path: "/upload",
}, func(ctx context.Context, input *struct {
RawBody huma.MultipartFormFiles[struct {
Avatar huma.FormFile `form:"avatar" contentType:"image/jpeg, image/png" required:"true"`
}]
}) (*struct{}, error) {
return nil, nil
})
},
Method: http.MethodPost,
URL: "/upload",
Headers: map[string]string{"Content-Type": "multipart/form-data; boundary=SimpleBoundary"},
Body: `--SimpleBoundary
Content-Disposition: form-data; name="avatar"

test
--SimpleBoundary--`,
Assert: func(t *testing.T, resp *httptest.ResponseRecorder) {
// Should return validation error, not panic
var errors huma.ErrorModel
err := json.Unmarshal(resp.Body.Bytes(), &errors)
require.NoError(t, err)
assert.Equal(t, "File required", errors.Errors[0].Message)
assert.Equal(t, "avatar", errors.Errors[0].Location)
assert.Equal(t, http.StatusUnprocessableEntity, resp.Code)
},
},
{
Name: "request-body-multipart-file-decoded-content-type-default",
Register: func(t *testing.T, api huma.API) {
Expand Down