danielgtaylor / danielgtaylor/huma
Bug: Exploded array query parameter ignores its declared default
- Dominant language
- Go
- Stars
- 4.4k
- Forks
- 285
- Avg merge
- 40m
- Merged PRs (30d)
- 1
Description
Hello 👋
I've found a thing that looks like a bug.
## Problem
An array query parameter declared with explode never receives its default when the parameter is absent from the request. The handler sees a nil slice instead.
The non-exploded form of the same declaration works correctly, and the generated OpenAPI document advertises the default in both cases. So the published spec and the runtime behaviour disagree.
Supplying the parameter explicitly works fine in both forms. Only the absent-parameter (default) path is broken, and only when explode is set.
If you want I already have a start of a fix ready locally and would be happy to push it.
Just wanted to ask if I was not mistaken and if it wasn't something expected before going deeper.
## Reproduction
My environment:
- huma v2.39.1
- Go 1.27.0 (macos)
```go
package repro
import (
"context"
"net/http"
"testing"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/humatest"
)
type Input struct {
Exploded []string `query:"exploded,explode" default:"a,b"`
NonExploded []string `query:"non-exploded" default:"a,b"`
}
type Output struct {
Body struct {
Exploded []string `json:"exploded"`
NonExploded []string `json:"non_exploded"`
}
}
func TestExplodeDefault(t *testing.T) {
_, api := humatest.New(t, huma.DefaultConfig("test", "1.0.0"))
huma.Register(api, huma.Operation{
OperationID: "demo",
Method: http.MethodGet,
Path: "/demo",
}, func(ctx context.Context, in *Input) (*Output, error) {
out := &Output{}
out.Body.Exploded = in.Exploded
out.Body.NonExploded = in.NonExploded
return out, nil
})
t.Log("no query params: ", api.Get("/demo").Body.String())
t.Log("params supplied: ", api.Get("/demo?exploded=a&exploded=b&non-exploded=a,b").Body.String())
}
```
Actual:
* no query params: {"exploded":null,"non_exploded":["a","b"]}
* params supplied: {"exploded":["a","b"],"non_exploded":["a","b"]}
Expected:
* no query params: {"exploded":["a","b"],"non_exploded":["a","b"]}
* params supplied: {"exploded":["a","b"],"non_exploded":["a","b"]}
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the TestExplodeDefault reproduction using humatest.New and huma.Register, then trace query decoding for the explode and default tags. Confirm the existing non-exploded behavior and explicit exploded values, then make the absent exploded parameter produce ["a","b"] as shown in the expected output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100