gofiber/fiber · error
unsupported value type: %T
Error message
unsupported value type: %T
What it means
Returned at binder/mapping.go:373 inside the generic formatBindData[T,K] when value is a string but the data map fails the any(data).(map[string][]string) assertion. formatBindData is called by the built-in binders (header/cookie/query/form/resp_header) with their T/K consistently, so this fires only when the generic is instantiated with mismatched types — i.e. a custom binder passes a string value while its data map is keyed for a different element type (e.g. files). It is a defensive invariant violation inside the binder layer.
Source
Thrown at binder/mapping.go:373
return content[:i]
}
return content
}
func formatBindData[T, K any](aliasTag string, out any, data map[string][]T, key string, value K, enableSplitting, supportBracketNotation bool) error { //nolint:revive // it's okay
var err error
if supportBracketNotation && strings.IndexByte(key, '[') >= 0 {
key, err = parseParamSquareBrackets(key)
if err != nil {
return err
}
}
switch v := any(value).(type) {
case string:
dataMap, ok := any(data).(map[string][]string)
if !ok {
return fmt.Errorf("unsupported value type: %T", value)
}
assignBindData(aliasTag, out, dataMap, key, v, enableSplitting)
case []string:
dataMap, ok := any(data).(map[string][]string)
if !ok {
return fmt.Errorf("unsupported value type: %T", value)
}
for _, val := range v {
assignBindData(aliasTag, out, dataMap, key, val, enableSplitting)
}
case []*multipart.FileHeader:
for _, val := range v {
valT, ok := any(val).(T)
if !ok {
return fmt.Errorf("unsupported value type: %T", value)
}View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Don't call formatBindData directly from app code — use the provided Bind().Header/Query/Cookie/Body/URI/Custom flow.
- If writing a custom binder, instantiate T and K consistently with the data map you pass (string values require map[string][]string).
- Unit-test the custom binder with a representative request so type mismatches surface immediately.
Defensive patterns
Strategy: type-guard
Validate before calling
// Prefer the built-in binders; if you must call formatBindData, instantiate
// T and K consistently with the data map.
var data = map[string][]string{}
if err := formatBindData[string, string]("query", out, data, key, "value", false, false); err != nil {
return err
} Type guard
// Ensure the data map element type matches the value type before calling.
func assertStringData(data any) (map[string][]string, bool) {
m, ok := data.(map[string][]string)
return m, ok
} Prevention
- Avoid calling binder.formatBindData from application code; use Bind().Query/Header/Cookie/Body/URI.
- In custom binders, keep the generic element type T aligned with both the data map and the value type.
- Unit-test custom binders with representative inputs to catch type mismatches early.
When it happens
Trigger: A custom CustomBinder implementation calls binder.formatBindData with K=string but supplies a data map of type map[string][]*multipart.FileHeader (or any non-string element), so the runtime type assertion fails. The built-in binders never hit this because they instantiate T/K coherently.
Common situations: Writing a custom binder for a non-standard source and reusing formatBindData with the wrong map/value type combo; copy-pasting a built-in binder and changing one type argument but not the map.
Related errors
- multiple binding_source tags found on struct %s
- unknown binding_source %q
- binder: custom binder not found, please be sure to enter the
- failed to type-assert to *Middleware
- failed to unmarshal xml: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/7f6bd2cf125d3925.json.
Report an issue: GitHub.