gofiber/fiber · error
binder: map is not convertible to map[string]string or map[s
Error message
binder: map is not convertible to map[string]string or map[string][]string
What it means
Returned by parseToMap (binder/mapping.go:153 and :160) when the destination map's element kind is Slice or String but the concrete type is not exactly map[string][]string or map[string]string. The binder can only populate those two shapes from form/query data; other slice/string element types (e.g. map[string][]int, map[string]MyString) cannot be filled without per-element conversion and are rejected.
Source
Thrown at binder/binder.go:20
import (
"errors"
"sync"
)
const (
bindingURI = "uri"
bindingForm = "form"
bindingQuery = "query"
bindingHeader = "header"
bindingRespHeader = "respHeader"
bindingCookie = "cookie"
)
// Binder errors
var (
ErrSuitableContentNotFound = errors.New("binder: suitable content not found to parse body")
ErrMapNotConvertible = errors.New("binder: map is not convertible to map[string]string or map[string][]string")
ErrMapNilDestination = errors.New("binder: map destination is nil and cannot be initialized")
ErrInvalidDestinationValue = errors.New("binder: invalid destination value")
ErrUnmatchedBrackets = errors.New("unmatched brackets")
)
var errPoolTypeAssertion = errors.New("failed to type-assert to T")
var HeaderBinderPool = sync.Pool{
New: func() any {
return &HeaderBinding{}
},
}
var RespHeaderBinderPool = sync.Pool{
New: func() any {
return &RespHeaderBinding{}
},
}View on GitHub (pinned to a105acad6c)
Solutions
- Change the destination to map[string][]string or map[string]string — the only two map shapes parseToMap populates.
- For typed values, bind into a struct with properly tagged fields instead of a map; the struct decoder handles type conversion.
- If you need map[string][]int, bind to map[string][]string first and convert values in a second pass with strconv.Atoi.
- Use map[string]any if you want the binder to skip the map (no-op) rather than error.
Example fix
// before
m := make(map[string][]int)
err := c.Bind().Query(&m) // ErrMapNotConvertible
// after
var s struct {
IDs []int `query:"ids"`
}
err := c.Bind().Query(&s) Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm the destination is one of the two supported map shapes
func isSupportedMap(t reflect.Type) bool {
return t == reflect.TypeFor[map[string]string]() ||
t == reflect.TypeFor[map[string][]string]()
} Type guard
func isSupportedMapDest(v any) bool {
t := reflect.TypeOf(v)
if t == nil || t.Kind() != reflect.Ptr { return false }
t = t.Elem()
return t == reflect.TypeFor[map[string]string]() || t == reflect.TypeFor[map[string][]string]()
} Try / catch
if err := c.Bind().Query(&m); err != nil {
if errors.Is(err, binder.ErrMapNotConvertible) {
// switch to a struct destination or map[string][]string
}
return err
} Prevention
- Prefer structs over maps for typed query/form binding.
- Restrict map destinations to map[string]string or map[string][]string.
- Add a unit test per handler that exercises the bind with realistic input.
When it happens
Trigger: Calling Bind.Query/Bind.Form (or any path that lands in parseToMap) with a destination of type map[string][]int, map[string]customStringType, or any map whose value kind is Slice/String but whose full type is not one of the two supported exact types.
Common situations: Trying to bind query parameters into a strongly-typed map like map[string][]int expecting automatic integer parsing; using a named string type as the map value; migrating a handler from map[string]string to a generic map[string]any (the latter is treated as a no-op, not an error).
Related errors
- binder: map destination is nil and cannot be initialized
- binder: invalid destination value
- binder: suitable content not found to parse body
- binder: must explicitly set up CBOR, please check docs: http
- binder: msgpack is not configured, please check docs: https:
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/3ad1ad2818e4bc74.
Report an issue: GitHub.