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

  1. Don't call formatBindData directly from app code — use the provided Bind().Header/Query/Cookie/Body/URI/Custom flow.
  2. If writing a custom binder, instantiate T and K consistently with the data map you pass (string values require map[string][]string).
  3. 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

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


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/7f6bd2cf125d3925.json. Report an issue: GitHub.