semaphoreui/semaphore · error
invalid migration version format
Error message
invalid migration version format %s
What it means
Migration.ParseVersion splits the Version string on '.' and requires at least two parts (major.minor) to build a comparable MigrationVersion. Versions with no dot — or empty strings reaching the parser — are rejected with this formatted error, surfaced through Compare when ordering migrations.
Solutions
- Rename/redefine the migration version to include both major and minor parts (e.g. "1.0", "3.2")
- Audit migration file names and the Version fields produced by the loader for missing dot separators
- Keep versions strictly in major.minor (optionally patch) format matching the project's existing migration history
Example fix
// before // migration file: 5__add_table.sql -> Version "5" // after // migration file: 5.0__add_table.sql -> Version "5.0"
Defensive patterns
Strategy: validation
Validate before calling
if len(strings.Split(m.Version, ".")) < 2 {
return fmt.Errorf("version %q must be in major.minor format", m.Version)
} Type guard
func isDottedVersion(v string) bool {
return len(strings.Split(v, ".")) >= 2
} Try / catch
if _, err := m.ParseVersion(); err != nil {
if strings.Contains(err.Error(), "invalid migration version format") {
return fmt.Errorf("bad migration version: %w", err)
}
return err
} Prevention
- Always use major.minor (optionally .patch) version strings for migrations
- Call m.Validate() before ParseVersion/Compare so empty versions fail earlier
- CI-check migration file names against a version regex (e.g. ^\d+\.\d+(\.\d+)?__)
When it happens
Trigger: Comparing or sorting migrations whose Version lacks a '.', e.g. "1", "v2", "" (when Validate was skipped), or a version accidentally stripped of its minor part by string processing.
Common situations: Hand-edited migration versions like "3" instead of "3.0"; scripts renaming migration files and dropping part of the version; mixing migration sets from forks using different versioning schemes.
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
- migration version is empty
- BoltDB not supported
- unsupported database driver
- database configuration not found
- Failed to link external account.
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/2ced26106ef4344b.
Report an issue: GitHub.
Appendix: source
Thrown at db/Migration.go:162
if m.Version == "" {
return fmt.Errorf("migration version is empty")
}
return nil
}
type MigrationVersion struct {
Major int
Minor int
Patch int
}
func (m Migration) ParseVersion() (res MigrationVersion, err error) {
parts := strings.Split(m.Version, ".")
if len(parts) < 2 {
err = fmt.Errorf("invalid migration version format %s", m.Version)
return
}
res.Major, err = strconv.Atoi(parts[0])
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
returnView on GitHub (pinned to 1774ccb71a)