{"record":{"id":"7059e7b868643d7b","repo":"go-gorm/gorm","slug":"invalid-foreign-key-s","errorCode":null,"errorMessage":"invalid foreign key: %s","messagePattern":"invalid foreign key: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/relationship.go","lineNumber":293,"sourceCode":"\t\terr             error\n\t\tjoinTableFields []reflect.StructField\n\t\tfieldsMap       = map[string]*Field{}\n\t\townFieldsMap    = map[string]*Field{} // fix self join many2many\n\t\treferFieldsMap  = map[string]*Field{}\n\t\tjoinForeignKeys = toColumns(field.TagSettings[\"JOINFOREIGNKEY\"])\n\t\tjoinReferences  = toColumns(field.TagSettings[\"JOINREFERENCES\"])\n\t)\n\n\townForeignFields := schema.PrimaryFields\n\trefForeignFields := relation.FieldSchema.PrimaryFields\n\n\tif len(relation.foreignKeys) > 0 {\n\t\townForeignFields = []*Field{}\n\t\tfor _, foreignKey := range relation.foreignKeys {\n\t\t\tif field := schema.LookUpField(foreignKey); field != nil {\n\t\t\t\townForeignFields = append(ownForeignFields, field)\n\t\t\t} else {\n\t\t\t\tschema.err = fmt.Errorf(\"invalid foreign key: %s\", foreignKey)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(relation.primaryKeys) > 0 {\n\t\trefForeignFields = []*Field{}\n\t\tfor _, foreignKey := range relation.primaryKeys {\n\t\t\tif field := relation.FieldSchema.LookUpField(foreignKey); field != nil {\n\t\t\t\trefForeignFields = append(refForeignFields, field)\n\t\t\t} else {\n\t\t\t\tschema.err = fmt.Errorf(\"invalid foreign key: %s\", foreignKey)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tfor idx, ownField := range ownForeignFields {","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/go-gorm/gorm/blob/1d6ce99528060be18a42be09aca8d39efcb47f28/schema/relationship.go#L275-L311","documentation":"While building a many-to-many relation, GORM validates explicit `foreignKey` tag values against the owner schema via LookUpField. Each named column must exist on the declaring struct; the first unknown name aborts with 'invalid foreign key: %s'. This is the own-side (owner) validation; the references side has its own check.","triggerScenarios":"`Members []User `gorm:\"many2many:user_tags;foreignKey:UserRef\"`` where the declaring struct has no field resolving to UserRef. Also triggered by case mismatches or names that only exist on the join table, not on the model.","commonSituations":"Renaming model fields during refactor without updating relation tags; pointing foreignKeys at join-table columns; typos or stale names after merging models.","solutions":["Correct the foreignKeys value to a field that exists on the declaring struct.","Drop the foreignKeys tag to let GORM default to the schema's primary fields.","If the key is embedded, use the exported field name reachable by LookUpField."],"exampleFix":"// before\ntype Tag struct {\n    ID      uint\n    Members []User `gorm:\"many2many:user_tags;foreignKey:TagUID\"`\n}\n\n// after\ntype Tag struct {\n    ID      uint\n    TagUID  string\n    Members []User `gorm:\"many2many:user_tags;foreignKey:TagUID\"`\n}","handlingStrategy":"validation","validationCode":"// Validate many2many foreignKeys resolve on the declaring struct\nfunc fieldExists(model any, name string) bool {\n    t := reflect.TypeOf(model)\n    for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice { t = t.Elem() }\n    _, ok := t.FieldByName(name)\n    return ok\n}\nif !fieldExists(&Tag{}, \"TagUID\") { panic(\"foreignKey TagUID missing on Tag\") }","typeGuard":null,"tryCatchPattern":"if err := db.AutoMigrate(&Tag{}); err != nil {\n    if strings.Contains(err.Error(), \"invalid foreign key\") {\n        return fmt.Errorf(\"foreignKeys tag must name a field on the declaring model: %w\", err)\n    }\n    return err\n}","preventionTips":["Remember: foreignKeys names a column on the DECLARING model, references on the RELATED model.","Rerun tag checks after renaming model fields (IDE rename does not update tag strings).","Default to omitting the tags; add them only for non-default keys."],"tags":["gorm","many2many","foreign-key","relation"],"backgroundTag":null,"analyzedSha":"1d6ce99528060be18a42be09aca8d39efcb47f28","analyzedAt":"2026-08-15T13:01:23.433Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}