go-gorm/gorm · error
unsupported data type: %v for relation %s
Error message
unsupported data type: %v for relation %s
What it means
While appending association values (Association.Append / Replace internals in association.go), each element ev must be assignable to the relation's element type elemType (directly or via pointer indirection). If neither ev.Type().AssignableTo(elemType) nor ev.Type().Elem().AssignableTo(elemType) holds, association.Error is set to fmt.Errorf("unsupported data type: %v for relation %s", ev.Type(), association.Relationship.Name).
Source
Thrown at association.go:430
}
case schema.HasMany, schema.Many2Many:
elemType := association.Relationship.Field.IndirectFieldType.Elem()
oldFieldValue := reflect.Indirect(association.Relationship.Field.ReflectValueOf(association.DB.Statement.Context, source))
var fieldValue reflect.Value
if clear {
fieldValue = reflect.MakeSlice(oldFieldValue.Type(), 0, oldFieldValue.Cap())
} else {
fieldValue = reflect.MakeSlice(oldFieldValue.Type(), oldFieldValue.Len(), oldFieldValue.Cap())
reflect.Copy(fieldValue, oldFieldValue)
}
appendToFieldValues := func(ev reflect.Value) {
if ev.Type().AssignableTo(elemType) {
fieldValue = reflect.Append(fieldValue, ev)
} else if ev.Type().Elem().AssignableTo(elemType) {
fieldValue = reflect.Append(fieldValue, ev.Elem())
} else {
association.Error = fmt.Errorf("unsupported data type: %v for relation %s", ev.Type(), association.Relationship.Name)
}
if elemType.Kind() == reflect.Struct {
assignBacks = append(assignBacks, assignBack{Source: source, Dest: ev, Index: fieldValue.Len()})
}
}
processMap := func(mapv reflect.Value) {
child := reflect.New(association.Relationship.FieldSchema.ModelType)
switch association.Relationship.Type {
case schema.HasMany:
for _, ref := range association.Relationship.References {
key := reflect.ValueOf(ref.ForeignKey.DBName)
if ref.OwnPrimaryKey {
v := ref.PrimaryKey.ReflectValueOf(association.DB.Statement.Context, source)
mapv.SetMapIndex(key, v)
} else if ref.PrimaryValue != "" {View on GitHub (pinned to 1d6ce99528)
Solutions
- Append values of exactly the relation's element type (or pointer to it) - check your struct tag's foreignKey model.
- Convert loosely-typed data into the concrete slice type before Append.
- Inspect association.Error after Append and log ev.Type() vs the relation name to find the mismatch.
- After changing a relation's model type, grep for all Append/Replace call sites on that relation.
Example fix
// before
assoc.Append([]interface{}{&Category{Name: "x"}}) // Category is not the relation model
// after
assoc.Append([]*Dog{{Name: "Rex"}}) Defensive patterns
Strategy: type-guard
Validate before calling
func matchRelationType(db *gorm.DB, model interface{}, rel string, vals []interface{}) error {
stmt := &gorm.Statement{DB: db}
if err := stmt.Parse(model); err != nil { return err }
r := stmt.Schema.Relationships.Relations[rel]
if r == nil { return gorm.ErrUnsupportedRelation }
for _, v := range vals {
if !reflect.TypeOf(v).AssignableTo(r.FieldSchema.ModelType) &&
!(reflect.TypeOf(v).Kind() == reflect.Ptr && reflect.TypeOf(v).Elem().AssignableTo(r.FieldSchema.ModelType)) {
return fmt.Errorf("value %T not assignable to %s", v, r.FieldSchema.ModelType)
}
}
return nil
} Type guard
func isRelationValue[T any](v interface{}) bool {
_, ok := v.(T)
if !ok {
p, isPtr := v.(*T)
return isPtr && p != nil
}
return ok
}
// usage: isRelationValue[Dog](item) Try / catch
if err := assoc.Append(values...); err != nil {
if strings.Contains(err.Error(), "unsupported data type") {
// re-typed values; build []*Dog and retry
}
} Prevention
- Type association payloads as concrete slices ([]*Dog), never []interface{}.
- After changing a relation's model type, fix every Append/Replace call site in the same commit.
When it happens
Trigger: Appending values whose type does not match the relation's declared model: appending *Category to a Pets []*Dog relation, appending a map/string where a struct is expected (the map path handles schema shape separately), or mixing pointer/non-pointer element types that do not line up with elemType.
Common situations: Generic code that accumulates interface{} values and appends them to associations; refactoring a relation's model type (Pet -> Dog) while callers still build old-type slices; JSON-decoded []interface{} passed straight into Append.
Related errors
- unsupported relationship
- unsupported relations: %s
- %s: unsupported relations for schema %s
- failed to assign association %#v, make sure foreign fields e
- invalid field type %#v for UnixSecondSerializer, only int, u
AI-assisted analysis of go-gorm/gorm@1d6ce99528 (2026-08-15).
Data as JSON: /api/errors/88e21efc06e991ea.
Report an issue: GitHub.