gin-gonic/gin · error
%q is not valid value for %s
Error message
%q is not valid value for %s
What it means
Returned by setByForm's reflect.Array branch (binding/form_mapping.go:302) when the number of values resolved for a form key does not equal the fixed length of the destination array. Arrays can't be resized, so a count mismatch is fatal — slices are the resizable alternative.
Source
Thrown at binding/form_mapping.go:302
// pre-process the default value for multi if present
cfTag := field.Tag.Get("collection_format")
if cfTag == "" || cfTag == "multi" {
vs = strings.Split(opt.defaultValue, ",")
}
}
if ok, err = trySetUsingParser(vs[0], value, opt.parser); ok {
return ok, err
} else if ok, err = trySetCustom(vs[0], value); ok {
return ok, err
}
if vs, err = trySplit(vs, field); err != nil {
return false, err
}
if len(vs) != value.Len() {
return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
}
return true, setArray(vs, value, field, opt)
default:
var val string
if !ok || len(vs) == 0 || (len(vs) > 0 && vs[0] == "") {
val = opt.defaultValue
} else if len(vs) > 0 {
val = vs[0]
}
if ok, err = trySetUsingParser(val, value, opt.parser); ok {
return ok, err
} else if ok, err = trySetCustom(val, value); ok {
return ok, err
}
return true, setWithProperType(val, value, field, opt)
}View on GitHub (pinned to 34dac209ff)
Solutions
- Change the field to a slice ([]string) so it accepts any count, then validate length explicitly.
- Keep the fixed array but make clients send exactly N values; document and validate the contract before binding.
- If you used collection_format csv, ensure the comma-separated list splits to exactly N elements.
Example fix
// before
type Q struct {
Coords [3]float64 `form:"coords"`
}
// after
type Q struct {
Coords []float64 `form:"coords"`
}
// then: if len(q.Coords) != 3 { c.AbortWithStatus(400) } Defensive patterns
Strategy: validation
Validate before calling
// before binding, count form values and compare to array length
if vs, ok := c.Request.Form["coords"]; ok && len(vs) != N {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("coords must have %d values", N)})
return
} Try / catch
if err := c.ShouldBind(&q); err != nil {
if strings.Contains(err.Error(), "is not valid value for") {
// wrong number of values for fixed array; switch to slice or fix client
}
} Prevention
- Prefer slices for variable-length form inputs.
- Validate the value count explicitly when you must use a fixed array.
- Document the exact count contract to clients.
When it happens
Trigger: Binding query/form into a struct field typed [3]string with a form value of tags=a,b (2 values) or tags=a,b,c,d (4); using collection_format csv but providing a comma list of the wrong length.
Common situations: Hard-coding array length for a fixed contract ("pass exactly 3 coordinates") and a client sending a different count; changing a slice to an array and forgetting to update clients.
Related errors
- unknown type
- can not convert to map slices of strings
- can not convert to map of strings
- unsupported len of array for []*multipart.FileHeader
- %s is not supported in the collection_format. (multi, csv, s
AI-assisted analysis of gin-gonic/gin@34dac209ff (2026-08-04).
Data as JSON: /data/errors/cd42847e8b88280e.json.
Report an issue: GitHub.