semaphoreui/semaphore · error
invalid migration version patch part
Error message
invalid migration version patch part %s
What it means
ParseVersion parses an optional third segment of a migration version string into the Patch field. If parts[2] exists but strconv.Atoi fails, it returns 'invalid migration version patch part %s'. Versions with only two parts are valid (Patch defaults to MaxInt).
Solutions
- Make the patch segment a plain integer, e.g. '1.2.3' instead of '1.2.hotfix'
- Drop the third segment if no numeric patch is needed — '1.2' is valid and yields Patch=MaxInt
- Trim stray dots/whitespace from version strings before parsing
Example fix
// before version = "1.2.rc1" // after version = "1.2.1"
Defensive patterns
Strategy: validation
Validate before calling
parts := strings.Split(version, ".")
if len(parts) > 2 {
if _, err := strconv.Atoi(parts[2]); err != nil {
return fmt.Errorf("patch part %q is not numeric", parts[2])
}
} Try / catch
if err := Compare(a, b); err != nil {
if strings.Contains(err.Error(), "patch part") {
return fmt.Errorf("use major.minor.patch with numeric patch: %w", err)
}
return err
} Prevention
- Use numeric patch segments only
- Omit the third segment entirely if no patch exists
- Reject version strings with trailing dots
When it happens
Trigger: Calling Compare/ParseVersion with a three-segment version whose patch segment is non-numeric, e.g. '1.2.hotfix' or '1.2.'.
Common situations: Appending labels like 'hotfix' or 'rc1' to the patch position; trailing dots in copied version strings; auto-generated names where patch is a date fragment with non-numeric chars.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid migration version major part
- invalid migration version minor part
- Failed to link external account.
- Internal Server Error
- no admins found in database; create a admin first
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/f0047e779e16727d.
Report an issue: GitHub.
Appendix: source
Thrown at db/Migration.go:185
if err != nil {
err = fmt.Errorf("invalid migration version major part %s", parts[0])
return
}
res.Minor, err = strconv.Atoi(parts[1])
if err != nil {
err = fmt.Errorf("invalid migration version minor part %s", parts[1])
return
}
if len(parts) < 3 {
res.Patch = math.MaxInt
return
}
res.Patch, err = strconv.Atoi(parts[2])
if err != nil {
err = fmt.Errorf("invalid migration version patch part %s", parts[2])
return
}
return
}
func (v MigrationVersion) Compare(o MigrationVersion) int {
if v.Major < o.Major {
return -1
} else if v.Major > o.Major {
return 1
}
if v.Minor < o.Minor {
return -1
} else if v.Minor > o.Minor {
return 1
}View on GitHub (pinned to 1774ccb71a)