beego/beego · error
one model must have one pk field only
Error message
one model must have one pk field only
What it means
A model was registered with more than one field marked `pk`. While collecting fields, beego assigns mi.Fields.Pk to the first pk field; a second field with fi.Pk set triggers 'one model must have one pk field only' and registration aborts (fatal via the 'field: ...' wrapper and os.Exit).
Source
Thrown at client/orm/internal/models/models_info_m.go:88
fi, err = NewFieldInfo(mi, field, sf, mName)
if err == errSkipField {
err = nil
continue
} else if err != nil {
break
}
// record current field index
fi.FieldIndex = append(fi.FieldIndex, index...)
fi.FieldIndex = append(fi.FieldIndex, i)
fi.Mi = mi
fi.InModel = true
if !mi.Fields.Add(fi) {
err = fmt.Errorf("duplicate column name: %s", fi.Column)
break
}
if fi.Pk {
if mi.Fields.Pk != nil {
err = fmt.Errorf("one model must have one pk field only")
break
} else {
mi.Fields.Pk = fi
}
}
}
if err != nil {
fmt.Println(fmt.Errorf("field: %s.%s, %s", ind.Type(), sf.Name, err))
os.Exit(2)
}
}
// NewM2MModelInfo combine related model info to new model info.
// prepare for relation models query.
func NewM2MModelInfo(m1, m2 *ModelInfo) (mi *ModelInfo) {
mi = new(ModelInfo)
mi.Fields = NewFields()View on GitHub (pinned to 939cfde380)
Solutions
- Keep exactly one pk per model, typically `Id int `orm:"pk;auto"``
- When embedding a base struct that already has the pk, do not declare another pk in the child
- For secondary unique keys use `unique` instead of `pk`
- For join tables, let beego auto-generate them (rel(m2m)) instead of hand-modeling composite keys
Example fix
// before Id int `orm:"pk;auto"` Email string `orm:"pk"` // after Id int `orm:"pk;auto"` Email string `orm:"unique"`
Defensive patterns
Strategy: validation
Validate before calling
func countPk(t reflect.Type) int {
n := 0
for i := 0; i < t.NumField(); i++ {
if strings.Contains(t.Field(i).Tag.Get("orm"), "pk") { n++ }
}
return n
}
// assert countPk == 1 for every registered model in a startup test Prevention
- One pk per struct; convention: Id int with pk;auto
- When embedding a BaseModel with pk, never add another
- Use `unique` for secondary keys
When it happens
Trigger: Two fields with `orm:"pk"` in one struct; a struct embedding a base model that already declares a pk while the child declares another; `orm:"pk;auto"` on Id plus `orm:"pk"` on a natural key like Email.
Common situations: Embedding a shared BaseModel (with Id pk) and redeclaring a pk in the child; composite-key habits from other ORMs — beego does not support composite primary keys via multiple pk tags.
Related errors
- wrong digits/decimals value %s/%s
- non-integer type cannot set auto
- auto primary key only support int, int32, int64, uint, uint3
- wrong tag format: `%s:"%s"`, %s
- duplicate column name: %s
AI-assisted analysis of beego/beego@939cfde380 (2026-08-15).
Data as JSON: /api/errors/f652e2082c803aea.
Report an issue: GitHub.