go-gorm/gorm · error

unsupported relationship

Error message

unsupported relationship

What it means

This error is the fallback return of setCreateOrUpdateG.handleAssociation in generics.go. That function implements association-level Unlink/Delete/Update operations by dispatching on the relationship type (HasOne, HasMany, BelongsTo, Many2Many) and the operation type (clause.OpUnlink, OpDelete, OpUpdate). If the relationship/op combination is not one of the handled cases, execution falls through the switch and returns errors.New("unsupported relationship"). It means GORM cannot translate the association operation you requested into SQL for this relation shape.

Source

Thrown at generics.go:911

		case clause.OpUpdate:
			// Update related table rows that have join rows matching owners
			relatedDB := base.Session(&Session{NewDB: true, Context: ctx}).Table(rel.FieldSchema.Table).Where(op.Conditions)

			// correlated join subquery: join.rel_fk = related.pk AND EXISTS owners
			joinSub := base.Session(&Session{NewDB: true, Context: ctx}).Table(rel.JoinTable.Table).Select("1")
			for _, ref := range rel.References {
				if !ref.OwnPrimaryKey && ref.PrimaryKey != nil {
					joinSub = joinSub.Where(clause.Eq{
						Column: clause.Column{Table: rel.JoinTable.Table, Name: ref.ForeignKey.DBName},
						Value:  clause.Column{Table: rel.FieldSchema.Table, Name: ref.PrimaryKey.DBName},
					})
				}
			}
			joinSub = joinSub.Where("EXISTS (?)", ownersExists)
			return relatedDB.Where("EXISTS (?)", joinSub).Updates(setMap).Error
		}
	}
	return errors.New("unsupported relationship")
}

View on GitHub (pinned to 1d6ce99528)

Solutions

  1. Use the public Association API operations that are implemented: Replace/Append/Delete/Clear (which map to Unlink/Delete/Update ops).
  2. Check the relation's gorm tags (foreignKey, references, joinForeignKey, joinReferences) and fix them so schema.Parse builds complete References.
  3. Print rel.Type and op.Type in a debug session to see which case is being skipped, then restructure the call to use a supported combination.
  4. For unsupported shapes (e.g. polymorphic join variants), perform the join-table or FK updates manually with db.Exec/db.Updates.

Example fix

// before: custom op falls through the switch
db.Model(&user).Association("Pets").Unscoped().Delete(&pet) // hits unsupported path via custom clause

// after: use the supported Delete op
db.Model(&user).Association("Pets").Delete(&pet)
Defensive patterns

Strategy: validation

Validate before calling

// before calling association ops, confirm the relation type is supported
assoc := tx.Model(&user).Association("Pets")
if assoc.Error != nil { return assoc.Error }
switch assoc.Relationship.Type {
case schema.HasOne, schema.HasMany, schema.BelongsTo, schema.Many2Many:
    // supported by handleAssociation
default:
    return fmt.Errorf("relation %s of type %v unsupported", "Pets", assoc.Relationship.Type)
}

Try / catch

if err := tx.Model(&user).Association("Pets").Delete(&pet); err != nil {
    if strings.Contains(err.Error(), "unsupported relationship") {
        // fall back to manual join-table / FK updates
    }
}

Prevention

When it happens

Trigger: Using the generics-based association mutation API (e.g. Association(column) driven ops) with an operation type other than Unlink/Delete/Update, or a relationship whose References are incomplete (nil PrimaryKey refs, e.g. broken composite/foreignKey tags) so it does not match any case; also any relation type that is not has-one/has-many/belongs-to/many-to-many.

Common situations: Custom association-op clauses built with clause.Association{Type: ...} values GORM does not handle; models where foreignKey/references tags are misdeclared so the parsed relationship has no usable references; code that worked against one GORM version but passes a new op type after upgrading; calling the internal generics path directly instead of the public Association API.

Related errors


AI-assisted analysis of go-gorm/gorm@1d6ce99528 (2026-08-15). Data as JSON: /api/errors/8b324b94128045a0. Report an issue: GitHub.