labstack/echo · error

unknown type

Error message

unknown type

What it means

Returned by setWithProperType in its default switch case when the destination field's reflect.Kind is not one of the supported scalar kinds (int/uint variants, bool, float32/64, string, pointer) and the field does not implement BindUnmarshaler or encoding.TextUnmarshaler. The binder has no logic to assign a string input to types like complex64, chan, func, map, array, or a nested struct.

Source

Thrown at bind.go:400

		return setUintField(val, 0, structField)
	case reflect.Uint8:
		return setUintField(val, 8, structField)
	case reflect.Uint16:
		return setUintField(val, 16, structField)
	case reflect.Uint32:
		return setUintField(val, 32, structField)
	case reflect.Uint64:
		return setUintField(val, 64, structField)
	case reflect.Bool:
		return setBoolField(val, structField)
	case reflect.Float32:
		return setFloatField(val, 32, structField)
	case reflect.Float64:
		return setFloatField(val, 64, structField)
	case reflect.String:
		structField.SetString(val)
	default:
		return errors.New("unknown type")
	}
	return nil
}

func unmarshalInputsToField(valueKind reflect.Kind, values []string, field reflect.Value) (bool, error) {
	if valueKind == reflect.Pointer {
		if field.IsNil() {
			field.Set(reflect.New(field.Type().Elem()))
		}
		field = field.Elem()
	}

	fieldIValue := field.Addr().Interface()
	unmarshaler, ok := fieldIValue.(bindMultipleUnmarshaler)
	if !ok {
		return false, nil
	}
	return true, unmarshaler.UnmarshalParams(values)

View on GitHub (pinned to 05489dc173)

Solutions

  1. Implement echo.BindUnmarshaler (UnmarshalParam) or encoding.TextUnmarshaler (UnmarshalText) on the field's type
  2. Change the field type to a supported scalar (string, int, float64) and convert it manually in the handler
  3. For nested data, bind from JSON body instead of flat query/form params

Example fix

// before
type Req struct {
    Matrix [4]float64 `query:"matrix"`
}

// after
type Req struct {
    Matrix string `query:"matrix"`
}
Defensive patterns

Strategy: type-guard

Type guard

// Ensure field types are supported by the binder
var supportedKinds = map[reflect.Kind]bool{
    reflect.Int: true, reflect.Int8: true, reflect.Int16: true,
    reflect.Int32: true, reflect.Int64: true,
    reflect.Uint: true, reflect.Uint8: true, reflect.Uint16: true,
    reflect.Uint32: true, reflect.Uint64: true,
    reflect.Bool: true, reflect.Float32: true, reflect.Float64: true,
    reflect.String: true, reflect.Pointer: true, reflect.Slice: true,
}
func hasUnsupportedFieldTypes(rt reflect.Type) error {
    for i := 0; i < rt.NumField(); i++ {
        f := rt.Field(i)
        if hasBindTag(f.Tag) && !supportedKinds[f.Type.Kind()] {
            return fmt.Errorf("field %s has unsupported kind %s", f.Name, f.Type.Kind())
        }
    }
    return nil
}

Try / catch

if err := c.Bind(&req); err != nil {
    if strings.Contains(err.Error(), "unknown type") {
        return echo.NewHTTPError(http.StatusBadRequest, "unsupported field type in request struct")
    }
    return err
}

Prevention

When it happens

Trigger: Binding a query/form/param/header value into a struct field whose type is complex64, a channel, a func, a map, an array, or a nested struct lacking a custom unmarshaler. Example: type Req struct{ C complex64 `query:"c"` }.

Common situations: Using uncommon numeric types (complex) in request DTOs. Having a field of type map[string]string or a nested struct expecting automatic conversion from a flat string param.

Related errors


AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04). Data as JSON: /data/errors/f9df1aae7be5c830.json. Report an issue: GitHub.