nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: danielgtaylor/huma
Pull request #323 (2024-03-18 01:14:13)

 feat(validation): flexible validation messages for pattern tag
Adds a new `patternDescription` struct tag to allow for human-readable error messages when using the pattern tag. 

Error messages are formatted like `expected string to be {description}` - this allows the user to use their own articles while still being consistent with the other validators




Patch:
diff --git a/schema.go b/schema.go
index 4bebcd5..25f1539 100644
--- a/schema.go
+++ b/schema.go
@@ -77,6 +77,7 @@ type Schema struct {
 	MinLength            *int                `yaml:"minLength,omitempty"`
 	MaxLength            *int                `yaml:"maxLength,omitempty"`
 	Pattern              string              `yaml:"pattern,omitempty"`
+	PatternDescription   string              `yaml:"patternDescription,omitempty"`
 	MinItems             *int                `yaml:"minItems,omitempty"`
 	MaxItems             *int                `yaml:"maxItems,omitempty"`
 	UniqueItems          bool                `yaml:"uniqueItems,omitempty"`
@@ -141,6 +142,7 @@ func (s *Schema) MarshalJSON() ([]byte, error) {
 		{"minLength", s.MinLength, omitEmpty},
 		{"maxLength", s.MaxLength, omitEmpty},
 		{"pattern", s.Pattern, omitEmpty},
+		{"patternDescription", s.PatternDescription, omitEmpty},
 		{"minItems", s.MinItems, omitEmpty},
 		{"maxItems", s.MaxItems, omitEmpty},
 		{"uniqueItems", s.UniqueItems, omitEmpty},
@@ -187,7 +189,11 @@ func (s *Schema) PrecomputeMessages() {
 	}
 	if s.Pattern != "" {
 		s.patternRe = regexp.MustCompile(s.Pattern)
-		s.msgPattern = "expected string to match pattern " + s.Pattern
+		if s.PatternDescription != "" {
+			s.msgPattern = "expected string to be " + s.PatternDescription
+		} else {
+			s.msgPattern = "expected string to match pattern " + s.Pattern
+		}
 	}
 	if s.MinItems != nil {
 		s.msgMinItems = fmt.Sprintf("expected array length >= %d", *s.MinItems)
@@ -498,6 +504,7 @@ func SchemaFromField(registry Registry, f reflect.StructField, hint string) *Sch
 	fs.MinLength = intTag(f, "minLength")
 	fs.MaxLength = intTag(f, "maxLength")
 	fs.Pattern = f.Tag.Get("pattern")
+	fs.PatternDescription = f.Tag.Get("patternDescription")
 	fs.MinItems = intTag(f, "minItems")
 	fs.MaxItems = intTag(f, "maxItems")
 	fs.UniqueItems = boolTag(f, "uniqueItems")


Test patch:
diff --git a/validate_test.go b/validate_test.go
index 20201cc..4a26261 100644
--- a/validate_test.go
+++ b/validate_test.go
@@ -265,6 +265,14 @@ var validateTests = []struct {
 		input: map[string]any{"value": "a1"},
 		errs:  []string{"expected string to match pattern ^[a-z]+$"},
 	},
+	{
+		name: "pattern custom message fail",
+		typ: reflect.TypeOf(struct {
+			Value string `json:"value" pattern:"^[a-z]+$" patternDescription:"alphabetical"`
+		}{}),
+		input: map[string]any{"value": "b@2"},
+		errs:  []string{"expected string to be alphabetical"},
+	},
 	{
 		name: "pattern invalid",
 		typ: reflect.TypeOf(struct {
Repository: danielgtaylor/huma
Pull request #341 (2024-03-28 15:25:38)

fix: support fields with ,omitempty but no name
Based on a [comment](https://github.com/danielgtaylor/huma/issues/238#issuecomment-2016448086) by @lazharichir this was an annoying bug where `json:",omitempty"` resulted in blank names in Huma-generated schemas. This is actually allowed by the standard library and means to just re-used the field name, so Huma now follows that same logic.


Patch:
diff --git a/schema.go b/schema.go
index cea21a9..47577f7 100644
--- a/schema.go
+++ b/schema.go
@@ -681,7 +681,9 @@ func SchemaFromType(r Registry, t reflect.Type) *Schema {
 			name := f.Name
 			omit := false
 			if j := f.Tag.Get("json"); j != "" {
-				name = strings.Split(j, ",")[0]
+				if n := strings.Split(j, ",")[0]; n != "" {
+					name = n
+				}
 				if strings.Contains(j, "omitempty") {
 					omit = true
 				}


Test patch:
diff --git a/schema_test.go b/schema_test.go
index 0034c49..76c6122 100644
--- a/schema_test.go
+++ b/schema_test.go
@@ -426,6 +426,21 @@ func TestSchema(t *testing.T) {
 				"required": ["value"]
 			}`,
 		},
+		{
+			name: "field-optional-without-name",
+			input: struct {
+				Value string `json:",omitempty"`
+			}{},
+			expected: `{
+				"type": "object",
+				"properties": {
+					"Value": {
+						"type": "string"
+					}
+				},
+				"additionalProperties": false
+			}`,
+		},
 		{
 			name: "field-example-custom",
 			input: struct {
Repository: danielgtaylor/huma
Pull request #396 (2024-04-19 14:49:56)

Support `netip.Addr` as a special type
Hey! I realised after opening my issue on this (#395), that this should be a pretty trivial issue to resolve. 

Please let me know if I've missed anything with this PR, and thanks again for all that you do!


Patch:
diff --git a/docs/docs/features/request-inputs.md b/docs/docs/features/request-inputs.md
index e66b1b0..60affd2 100644
--- a/docs/docs/features/request-inputs.md
+++ b/docs/docs/features/request-inputs.md
@@ -61,10 +61,11 @@ The special struct field `Body` will be treated as the input request body and ca
 The following special types are supported out of the box:
 
 | Type              | Schema                                      | Example                       |
-| ----------------- | ------------------------------------------- | ----------------------------- |
+|-------------------| ------------------------------------------- | ----------------------------- |
 | `time.Time`       | `{"type": "string", "format": "date-time"}` | `"2020-01-01T12:00:00Z"`      |
 | `url.URL`         | `{"type": "string", "format": "uri"}`       | `"https://example.com"`       |
 | `net.IP`          | `{"type": "string", "format": "ipv4"}`      | `"127.0.0.1"`                 |
+| `netip.Addr`      | `{"type": "string", "format": "ipv4"}`      | `"127.0.0.1"`                 |
 | `json.RawMessage` | `{}`                                        | `["whatever", "you", "want"]` |
 
 You can override this default behavior if needed as described in [Schema Customization](./schema-customization.md) and [Request Validation](./request-validation.md), e.g. setting a custom `format` tag for IPv6.
diff --git a/schema.go b/schema.go
index eaca727..dacd489 100644
--- a/schema.go
+++ b/schema.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"math/bits"
 	"net"
+	"net/netip"
 	"net/url"
 	"reflect"
 	"regexp"
@@ -32,6 +33,7 @@ const (
 var (
 	timeType       = reflect.TypeOf(time.Time{})
 	ipType         = reflect.TypeOf(net.IP{})
+	ipAddrType     = reflect.TypeOf(netip.Addr{})
 	urlType        = reflect.TypeOf(url.URL{})
 	rawMessageType = reflect.TypeOf(json.RawMessage{})
 )
@@ -618,6 +620,8 @@ func SchemaFromType(r Registry, t reflect.Type) *Schema {
 		return &Schema{Type: TypeString, Nullable: isPointer, Format: "uri"}
 	case ipType:
 		return &Schema{Type: TypeString, Nullable: isPointer, Format: "ipv4"}
+	case ipAddrType:
+		return &Schema{Type: TypeString, Nullable: isPointer, Format: "ipv4"}
 	case rawMessageType:
 		return &Schema{}
 	}


Test patch:
diff --git a/schema_test.go b/schema_test.go
index ea64b81..d88e496 100644
--- a/schema_test.go
+++ b/schema_test.go
@@ -5,6 +5,7 @@ import (
 	"encoding/json"
 	"math/bits"
 	"net"
+	"net/netip"
 	"net/url"
 	"reflect"
 	"strconv"
@@ -149,6 +150,11 @@ func TestSchema(t *testing.T) {
 			input:    net.IPv4(127, 0, 0, 1),
 			expected: `{"type": "string", "format": "ipv4"}`,
 		},
+		{
+			name:     "ipAddr",
+			input:    netip.AddrFrom4([4]byte{127, 0, 0, 1}),
+			expected: `{"type": "string", "format": "ipv4"}`,
+		},
 		{
 			name:     "json.RawMessage",
 			input:    &json.RawMessage{},
Repository: danielgtaylor/huma
Pull request #413 (2024-04-26 10:21:39)

fix: check if struct implements interface SchemaProvider after deref
Problem:
Currently the Schema(r Registry) *Schema on types that implement a custom schema will only be called if the field is not a pointer. 

Solution:
In the function SchemaFromType we first deref the type so that we always compare a non pointer type against the interface. 

fixes: #412 


Patch:
diff --git a/schema.go b/schema.go
index dacd489..accb2a9 100644
--- a/schema.go
+++ b/schema.go
@@ -601,17 +601,17 @@ type SchemaProvider interface {
 //	registry := huma.NewMapRegistry("#/prefix", huma.DefaultSchemaNamer)
 //	schema := huma.SchemaFromType(registry, reflect.TypeOf(MyType{}))
 func SchemaFromType(r Registry, t reflect.Type) *Schema {
+	isPointer := t.Kind() == reflect.Pointer
+
+	s := Schema{}
+	t = deref(t)
+
 	v := reflect.New(t).Interface()
 	if sp, ok := v.(SchemaProvider); ok {
 		// Special case: type provides its own schema. Do not try to generate.
 		return sp.Schema(r)
 	}
 
-	isPointer := t.Kind() == reflect.Pointer
-
-	s := Schema{}
-	t = deref(t)
-
 	// Handle special cases.
 	switch t {
 	case timeType:


Test patch:
diff --git a/schema_test.go b/schema_test.go
index d88e496..4ae63e6 100644
--- a/schema_test.go
+++ b/schema_test.go
@@ -479,6 +479,23 @@ func TestSchema(t *testing.T) {
 				"required": ["value"]
 			}`,
 		},
+		{
+			name: "field-example-custom-pointer",
+			input: struct {
+				Value *CustomSchema `json:"value" example:"foo"`
+			}{},
+			expected: `{
+				"type": "object",
+				"properties": {
+					"value": {
+						"type": "string",
+						"examples": ["foo"]
+					}
+				},
+				"additionalProperties": false,
+				"required": ["value"]
+			}`,
+		},
 		{
 			name: "field-enum-custom",
 			input: struct {
Repository: danielgtaylor/huma
Pull request #418 (2024-04-28 02:40:30)

fix: more robust nil check for link transformer
This uses reflection to check for nil which is more robust and can prevent a panic/500 error from happening if the operation returns successful with a nil body.


Patch:
diff --git a/transforms.go b/transforms.go
index c8600c0..9c5a0db 100644
--- a/transforms.go
+++ b/transforms.go
@@ -150,7 +150,8 @@ func (t *SchemaLinkTransformer) OnAddOperation(oapi *OpenAPI, op *Operation) {
 // Transform is called for every response to add the `$schema` field and/or
 // the Link header pointing to the JSON Schema.
 func (t *SchemaLinkTransformer) Transform(ctx Context, status string, v any) (any, error) {
-	if v == nil {
+	vv := reflect.ValueOf(v)
+	if vv.Kind() == reflect.Pointer && vv.IsNil() {
 		return v, nil
 	}
 
@@ -184,7 +185,7 @@ func (t *SchemaLinkTransformer) Transform(ctx Context, status string, v any) (an
 	bufPool.Put(buf)
 
 	// Copy over all the exported fields.
-	vv := reflect.Indirect(reflect.ValueOf(v))
+	vv = reflect.Indirect(vv)
 	for i, j := range info.fields {
 		// Field 0 is the $schema field, so we need to offset the index by one.
 		// There might have been unexported fields in the struct declared in the schema,


Test patch:
diff --git a/huma_test.go b/huma_test.go
index 5aa6364..9af8c40 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -1114,6 +1114,30 @@ Content of example2.txt.
 				assert.Equal(t, `hello`, resp.Body.String())
 			},
 		},
+		{
+			Name: "response-transform-nil-body",
+			Transformers: []huma.Transformer{
+				huma.NewSchemaLinkTransformer("/", "/").Transform,
+			},
+			Register: func(t *testing.T, api huma.API) {
+				huma.Get(api, "/transform", func(ctx context.Context, i *struct{}) (*struct {
+					Body *struct {
+						Field string `json:"field"`
+					}
+				}, error) {
+					return &struct {
+						Body *struct {
+							Field string `json:"field"`
+						}
+					}{}, nil
+				})
+			},
+			Method: http.MethodGet,
+			URL:    "/transform",
+			Assert: func(t *testing.T, resp *httptest.ResponseRecorder) {
+				assert.Equal(t, http.StatusOK, resp.Code)
+			},
+		},
 		{
 			Name: "response-transform-error",
 			Transformers: []huma.Transformer{
Repository: danielgtaylor/huma
Pull request #431 (2024-05-04 20:53:43)

panic with more descriptive messages
Ran into this problem where a dev tried to use *int for a response, and the panic wasn't clear about what to fix. This tries to point the dev in the right direction.


Patch:
diff --git a/huma.go b/huma.go
index f6b1456..9a21d86 100644
--- a/huma.go
+++ b/huma.go
@@ -1421,7 +1421,11 @@ var reRemoveIDs = regexp.MustCompile(`\{([^}]+)\}`)
 // This function can be overridden to provide custom operation IDs.
 var GenerateOperationID = func(method, path string, response any) string {
 	action := method
-	body, hasBody := deref(reflect.TypeOf(response)).FieldByName("Body")
+	t := deref(reflect.TypeOf(response))
+	if t.Kind() != reflect.Struct {
+		panic("Response type must be a struct")
+	}
+	body, hasBody := t.FieldByName("Body")
 	if hasBody && method == http.MethodGet && deref(body.Type).Kind() == reflect.Slice {
 		// Special case: GET with a slice response body is a list operation.
 		action = "list"
@@ -1443,7 +1447,11 @@ var GenerateOperationID = func(method, path string, response any) string {
 // This function can be overridden to provide custom operation summaries.
 var GenerateSummary = func(method, path string, response any) string {
 	action := method
-	body, hasBody := deref(reflect.TypeOf(response)).FieldByName("Body")
+	t := deref(reflect.TypeOf(response))
+	if t.Kind() != reflect.Struct {
+		panic("Response type must be a struct")
+	}
+	body, hasBody := t.FieldByName("Body")
 	if hasBody && method == http.MethodGet && deref(body.Type).Kind() == reflect.Slice {
 		// Special case: GET with a slice response body is a list operation.
 		action = "list"


Test patch:
diff --git a/huma_test.go b/huma_test.go
index 77f1887..5607e82 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -1904,3 +1904,15 @@ func BenchmarkHandlerFunc(b *testing.B) {
 		}
 	})
 }
+
+func TestGenerateFuncsPanicWithDescriptiveMessage(t *testing.T) {
+	var resp *int
+	assert.PanicsWithValue(t, "Response type must be a struct", func() {
+		huma.GenerateOperationID("GET", "/foo", resp)
+	})
+
+	assert.PanicsWithValue(t, "Response type must be a struct", func() {
+		huma.GenerateSummary("GET", "/foo", resp)
+	})
+
+}
Repository: danielgtaylor/huma
Pull request #532 (2024-08-02 02:04:23)

fix(schema): schema example not work in Parameter
```go
type GreetingType int

func (*GreetingType) Schema(r huma.Registry) *huma.Schema {
	schema := &huma.Schema{
		Type:     huma.TypeInteger,
		Examples: []any{1},
	}
	return schema
}

```

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit


- **New Features**
	- Enhanced example generation logic for improved flexibility and usability in the application.
	- Default examples are now utilized when no explicit examples are defined, enriching the user experience.
	- Introduced a new integer type with an example value, improving API documentation clarity.
- **Tests**
	- Added a test to validate the new integer type's behavior within the API context.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Patch:
diff --git a/huma.go b/huma.go
index f3fd562..65187c2 100644
--- a/huma.go
+++ b/huma.go
@@ -167,6 +167,9 @@ func findParams(registry Registry, op *Operation, t reflect.Type) *findResult[*p
 		if e := f.Tag.Get("example"); e != "" {
 			example = jsonTagValue(registry, f.Type.Name(), pfi.Schema, f.Tag.Get("example"))
 		}
+		if example == nil && len(pfi.Schema.Examples) > 0 {
+			example = pfi.Schema.Examples[0]
+		}
 
 		// While discouraged, make it possible to make query/header params required.
 		if r := f.Tag.Get("required"); r == "true" {


Test patch:
diff --git a/huma_test.go b/huma_test.go
index 7904164..9e1f570 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -2134,6 +2134,32 @@ func TestUnsupportedEmbeddedTypeWithMethods(t *testing.T) {
 	})
 }
 
+type SchemaWithExample int
+
+func (*SchemaWithExample) Schema(r huma.Registry) *huma.Schema {
+	schema := &huma.Schema{
+		Type:     huma.TypeInteger,
+		Examples: []any{1},
+	}
+	return schema
+}
+
+func TestSchemaWithExample(t *testing.T) {
+	_, app := humatest.New(t, huma.DefaultConfig("Test API", "1.0.0"))
+	huma.Register(app, huma.Operation{
+		OperationID: "test",
+		Method:      http.MethodGet,
+		Path:        "/test",
+	}, func(ctx context.Context, input *struct {
+		Test SchemaWithExample `query:"test"`
+	}) (*struct{}, error) {
+		return nil, nil
+	})
+
+	example := app.OpenAPI().Paths["/test"].Get.Parameters[0].Example
+	assert.Equal(t, 1, example)
+}
+
 // func BenchmarkSecondDecode(b *testing.B) {
 // 	//nolint: musttag
 // 	type MediumSized struct {
Repository: danielgtaylor/huma
Pull request #656 (2024-11-20 00:40:53)

Exclude embedded fields in response header docs
Ignore embedded fields when finding response headers (resolves https://github.com/danielgtaylor/huma/issues/655)

Not sure if it’s intentional that any field regardless of if tagged with `header` is considered a response header. If that’s not your intent, we could simplify this by returning `nil` when `header == “”`

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
	- Improved header processing logic to ignore embedded fields, ensuring only explicitly defined struct fields are considered for header extraction.
	- Added pagination headers to the API response structure, allowing for pagination information to be included.

- **Bug Fixes**
	- Enhanced clarity and specificity in header handling within the API framework.
	- Expanded test coverage for cookie handling, middleware behavior, and request parameter validation.
	- Improved error handling in tests with additional assertions for invalid inputs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Patch:
diff --git a/huma.go b/huma.go
index 448685e..6596be8 100644
--- a/huma.go
+++ b/huma.go
@@ -230,6 +230,11 @@ type headerInfo struct {
 
 func findHeaders(t reflect.Type) *findResult[*headerInfo] {
 	return findInType(t, nil, func(sf reflect.StructField, i []int) *headerInfo {
+		// Ignore embedded fields
+		if sf.Anonymous {
+			return nil
+		}
+
 		header := sf.Tag.Get("header")
 		if header == "" {
 			header = sf.Name


Test patch:
diff --git a/huma_test.go b/huma_test.go
index d5e984b..b3dd5b1 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -1935,7 +1935,13 @@ Content of example2.txt.
 func TestOpenAPI(t *testing.T) {
 	r, api := humatest.New(t, huma.DefaultConfig("Features Test API", "1.0.0"))
 
+	// Used to validate exclusion of embedded structs from response headers
+	type PaginationHeaders struct {
+		Link string `header:"link"`
+	}
+
 	type Resp struct {
+		PaginationHeaders
 		Body struct {
 			Greeting string `json:"greeting"`
 		}
@@ -1964,6 +1970,17 @@ func TestOpenAPI(t *testing.T) {
 
 		assert.Equal(t, 200, w.Code, w.Body.String())
 	}
+
+	t.Run("ignore-anonymous-header-structs", func(t *testing.T) {
+		req, _ := http.NewRequest(http.MethodGet, "/openapi.yaml", nil)
+		w := httptest.NewRecorder()
+		r.ServeHTTP(w, req)
+
+		openapiBody := w.Body.String()
+		assert.Equal(t, 200, w.Code, openapiBody)
+		assert.Contains(t, openapiBody, "link")
+		assert.NotContains(t, openapiBody, "PaginationHeaders")
+	})
 }
 
 type IntNot3 int
Repository: danielgtaylor/huma
Pull request #760 (2025-03-13 17:41:51)

feat: adding the head method to the list of convenience wrappers
Hi,

Thank you again for your work on this project!

I just noticed that the `head` method is missing here. Hopefully, this small addition will be helpful to others. :)


Patch:
diff --git a/huma.go b/huma.go
index 0ef57dd..c58a0ed 100644
--- a/huma.go
+++ b/huma.go
@@ -2048,7 +2048,7 @@ func convenience[I, O any](api API, method, path string, handler func(context.Co
 //		Body []Thing
 //	}) (*ListThingOutput, error) {
 //		// TODO: list things from DB...
-//		resp := &PostThingOutput{}
+//		resp := &ListThingOutput{}
 //		resp.Body = []Thing{{ID: "1", Name: "Thing 1"}}
 //		return resp, nil
 //	})
@@ -2079,6 +2079,26 @@ func Post[I, O any](api API, path string, handler func(context.Context, *I) (*O,
 	convenience(api, http.MethodPost, path, handler, operationHandlers...)
 }
 
+// Head HTTP operation handler for an API. The handler must be a function that
+// takes a context and a pointer to the input struct and returns a pointer to the
+// output struct and an error. The input struct must be a struct with fields
+// for the request path/query/header/cookie parameters. The output struct must be a
+// struct with fields for the output headers of the operation, if any.
+//
+//	huma.Head(api, "/things/{thing-id}", func(ctx context.Context, input *struct{
+//		ID string `path:"thing-id"`
+//		Header string `header:"X-My-Header"`
+//	}) (*HeadThingOutput, error) {
+//		// TODO: get info from DB...
+//		resp := &HeadThingOutput{}
+//		return resp, nil
+//	})
+//
+// This is a convenience wrapper around `huma.Register`.
+func Head[I, O any](api API, path string, handler func(context.Context, *I) (*O, error), operationHandlers ...func(o *Operation)) {
+	convenience(api, http.MethodHead, path, handler, operationHandlers...)
+}
+
 // Put HTTP operation handler for an API. The handler must be a function that
 // takes a context and a pointer to the input struct and returns a pointer to the
 // output struct and an error. The input struct must be a struct with fields


Test patch:
diff --git a/huma_test.go b/huma_test.go
index e83b0bf..83e9747 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -2899,6 +2899,12 @@ func TestConvenienceMethods(t *testing.T) {
 	assert.Equal(t, []string{"Things"}, api.OpenAPI().Paths[path].Post.Tags)
 
 	path = path + "/{thing-id}"
+	huma.Head(api, path, func(ctx context.Context, input *Input) (*struct{}, error) {
+		return nil, nil
+	}, huma.OperationTags("Things"))
+	assert.Equal(t, "head-things-by-thing-id", api.OpenAPI().Paths[path].Head.OperationID)
+	assert.Equal(t, []string{"Things"}, api.OpenAPI().Paths[path].Head.Tags)
+
 	huma.Put(api, path, func(ctx context.Context, input *Input) (*struct{}, error) {
 		return nil, nil
 	}, huma.OperationTags("Things"))
Repository: danielgtaylor/huma
Pull request #765 (2025-03-15 19:25:50)

fix: do not HTML escape JSON output by default
Be default, JSON output is escaped to better support embedding it into HTML. This is extremely unlikely to be needed for HTTP APIs as they have different access patterns. This changes the default behavior to not escape, while letting people who do need the feature set it up in their `huma.Config.Formats` map as needed.

For example, `expected number \u003e= 10` becomes `expected number >= 10` after this change.


Patch:
diff --git a/README.md b/README.md
index a37864b..e5e863e 100644
--- a/README.md
+++ b/README.md
@@ -88,7 +88,6 @@ A big thank you to our current & former sponsors!
 - [@chenjr0719](https://github.com/chenjr0719)
 - [@vinogradovkonst](https://github.com/vinogradovkonst)
 - [@miyamo2](https://github.com/miyamo2)
-- [@nielskrijger](https://github.com/nielskrijger)
 
 ## Testimonials
 
diff --git a/defaults.go b/defaults.go
index 362d292..4418c4d 100644
--- a/defaults.go
+++ b/defaults.go
@@ -15,7 +15,9 @@ import (
 //	}
 var DefaultJSONFormat = Format{
 	Marshal: func(w io.Writer, v any) error {
-		return json.NewEncoder(w).Encode(v)
+		enc := json.NewEncoder(w)
+		enc.SetEscapeHTML(false)
+		return enc.Encode(v)
 	},
 	Unmarshal: json.Unmarshal,
 }
diff --git a/docs/docs/index.md b/docs/docs/index.md
index f302736..97a7178 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -11,7 +11,6 @@ sponsors:
     - chenjr0719
     - vinogradovkonst
     - miyamo2
-    - nielskrijger
 ---
 
 # Huma {.hidden}


Test patch:
diff --git a/huma_test.go b/huma_test.go
index 83e9747..2e56a2f 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -3002,7 +3002,7 @@ func TestCustomSchemaErrors(t *testing.T) {
 	resp := api.Post("/test", map[string]any{"test": 1})
 
 	assert.Equal(t, http.StatusUnprocessableEntity, resp.Result().StatusCode)
-	assert.Contains(t, resp.Body.String(), `expected number \u003e= 10`)
+	assert.Contains(t, resp.Body.String(), `expected number >= 10`)
 }
 
 func TestBodyRace(t *testing.T) {