go-gorm/gorm · error

invalid polymorphic type %v for %v on field %s, missing prim

Error message

invalid polymorphic type %v for %v on field %s, missing primaryKey field

What it means

After resolving the polymorphic foreign key, GORM needs a non-nil primary key field on the owner schema (either the tagged foreignKeys[0] or schema.PrioritizedPrimaryField). If the owner struct has no primary key at all (no `gorm:"primaryKey"` and no conventional ID field), primaryKeyField stays nil and this error is returned.

Source

Thrown at schema/relationship.go:247

			relation.FieldSchema, schema, field.Name, polymorphic+"ID")
	}

	if schema.err == nil {
		relation.References = append(relation.References, &Reference{
			PrimaryValue: relation.Polymorphic.Value,
			ForeignKey:   relation.Polymorphic.PolymorphicType,
		})

		primaryKeyField := schema.PrioritizedPrimaryField
		if len(relation.foreignKeys) > 0 {
			if primaryKeyField = schema.LookUpField(relation.foreignKeys[0]); primaryKeyField == nil || len(relation.foreignKeys) > 1 {
				schema.err = fmt.Errorf("invalid polymorphic foreign keys %+v for %v on field %s", relation.foreignKeys,
					schema, field.Name)
			}
		}

		if primaryKeyField == nil {
			schema.err = fmt.Errorf("invalid polymorphic type %v for %v on field %s, missing primaryKey field",
				relation.FieldSchema, schema, field.Name)
			return
		}

		// use same data type for foreign keys
		if copyableDataType(primaryKeyField.DataType) {
			relation.Polymorphic.PolymorphicID.DataType = primaryKeyField.DataType
		}
		relation.Polymorphic.PolymorphicID.GORMDataType = primaryKeyField.GORMDataType
		if relation.Polymorphic.PolymorphicID.Size == 0 {
			relation.Polymorphic.PolymorphicID.Size = primaryKeyField.Size
		}

		relation.References = append(relation.References, &Reference{
			PrimaryKey:    primaryKeyField,
			ForeignKey:    relation.Polymorphic.PolymorphicID,
			OwnPrimaryKey: true,
		})

View on GitHub (pinned to 1d6ce99528)

Solutions

  1. Define a primary key on the owner struct: `ID uint `gorm:"primaryKey"``.
  2. Or tag an existing unique column with `gorm:"primaryKey"`.
  3. If foreignKeys was specified, verify the referenced field exists on the owner (not the related) schema.

Example fix

// before
type Owner struct {
    Name string // no primary key
    Pets []Pet `gorm:"polymorphic:Owner"`
}

// after
type Owner struct {
    ID   uint `gorm:"primaryKey"`
    Name string
    Pets []Pet `gorm:"polymorphic:Owner"`
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure owner has a primary key before declaring polymorphic children
if _, err := schema.Parse(&Owner{}, &sync.Map{}, schema.NamingStrategy{}); err != nil {
    return err // or inspect .PrioritizedPrimaryField == nil

Try / catch

if err := db.AutoMigrate(&Owner{}, &Pet{}); err != nil {
    if strings.Contains(err.Error(), "missing primaryKey field") {
        return fmt.Errorf("owner model needs a primary key: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Owner model lacks any primary key: no field named ID, no `gorm:"primaryKey"` tag, and no DeletedAt-style prioritized field; or the foreignKeys lookup silently failed in a prior branch leaving the variable nil.

Common situations: Join/view structs used as polymorphic owners without a key; composite-key structs where every key column is tagged differently; embedding models where the key lives in an unexported field.

Related errors


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