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

  1. Change the destination to map[string][]string or map[string]string — the only two map shapes parseToMap populates.
  2. For typed values, bind into a struct with properly tagged fields instead of a map; the struct decoder handles type conversion.
  3. If you need map[string][]int, bind to map[string][]string first and convert values in a second pass with strconv.Atoi.
  4. 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

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


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/3ad1ad2818e4bc74. Report an issue: GitHub.