gin-gonic/gin · error

type (%T) unknown type

Error message

type (%T) unknown type

What it means

Returned by plainBinding.decodePlain (binding/plain.go:55) when the binding target — after dereferencing pointers — is neither a string nor a []byte. Plain binding just copies the raw body bytes; it has no schema parser, so any other destination type is unsupported.

Source

Thrown at binding/plain.go:55

	for v.Kind() == reflect.Ptr {
		if v.IsNil() {
			return nil
		}
		v = v.Elem()
	}

	if v.Kind() == reflect.String {
		v.SetString(bytesconv.BytesToString(data))
		return nil
	}

	if _, ok := v.Interface().([]byte); ok {
		v.SetBytes(data)
		return nil
	}

	return fmt.Errorf("type (%T) unknown type", v)
}

View on GitHub (pinned to 34dac209ff)

Solutions

  1. Make the target *string or *[]byte and parse the value yourself (strconv.Atoi etc.).
  2. If the body is actually JSON, use binding.JSON / c.ShouldBindJSON instead.
  3. Implement binding.BindUnmarshaler on a custom type if you want plain text to populate it.

Example fix

// before
var n int
c.ShouldBindWith(&n, binding.Plain)
// after
var raw string
c.ShouldBindWith(&raw, binding.Plain)
n, err := strconv.Atoi(strings.TrimSpace(raw))
Defensive patterns

Strategy: type-guard

Validate before calling

v := reflect.ValueOf(obj)
for v.Kind() == reflect.Ptr { v = v.Elem() }
if v.Kind() != reflect.String && v.Type() != reflect.TypeOf([]byte{}) {
    return fmt.Errorf("plain binding target must be string or []byte, got %T", obj)
}

Type guard

func isPlainBindable(v any) bool {
    rv := reflect.ValueOf(v)
    for rv.Kind() == reflect.Ptr { rv = rv.Elem() }
    return rv.Kind() == reflect.String || rv.Type() == reflect.TypeOf([]byte{})
}

Try / catch

if err := c.ShouldBindWith(&raw, binding.Plain); err != nil {
    if strings.Contains(err.Error(), "unknown type") {
        // target was not string/[]byte; switch target or use a different binding
    }
}

Prevention

When it happens

Trigger: Calling binding.Plain.Bind / c.ShouldBindWith(&obj, binding.Plain) where obj points to an int, struct, map, or any non-string/[]byte type.

Common situations: Trying to bind a text/plain body to a struct (should use JSON or form binding); binding to *int expecting strconv conversion; pointing obj at a custom typed alias of string that does not satisfy reflect after deref (rare).

Related errors


AI-assisted analysis of gin-gonic/gin@34dac209ff (2026-08-04). Data as JSON: /data/errors/27f3ee9a39d81b50.json. Report an issue: GitHub.