golang-migrate/migrate · error
unable to parse file %v
Error message
unable to parse file %v
What it means
Raised by the go-bindata driver's WithInstance while iterating assets: when a file parses successfully (passes DefaultParse) but its version number collides with an already-appended migration, Append returns false and the driver fails with 'unable to parse file %v'. Files that fail parsing outright are silently skipped, so this error specifically indicates duplicate version numbers.
Source
Thrown at source/go_bindata/go-bindata.go:63
if _, ok := instance.(*AssetSource); !ok {
return nil, ErrNoAssetSource
}
as := instance.(*AssetSource)
bn := &Bindata{
path: "<go-bindata>",
assetSource: as,
migrations: source.NewMigrations(),
}
for _, fi := range as.Names {
m, err := source.DefaultParse(fi)
if err != nil {
continue // ignore files that we can't parse
}
if !bn.migrations.Append(m) {
return nil, fmt.Errorf("unable to parse file %v", fi)
}
}
return bn, nil
}
func (b *Bindata) Close() error {
return nil
}
func (b *Bindata) First() (version uint, err error) {
if v, ok := b.migrations.First(); !ok {
return 0, &os.PathError{Op: "first", Path: b.path, Err: os.ErrNotExist}
} else {
return v, nil
}
}
View on GitHub (pinned to 01a9643f14)
Solutions
- List the embedded asset names and find files resolving to the same version number
- Rename the duplicate to a unique, higher version number
- Regenerate the bindata asset bundle after renaming so stale entries are removed
- Exclude non-migration copies (e.g. .bak, editor backups) from the embedded assets
Example fix
// before (embedded assets) 002_add_index.sql 002_add_index.sql.bak // after — remove or rename the .bak, then regenerate assets 002_add_index.sql
Defensive patterns
Strategy: validation
Validate before calling
names := AssetDir("migrations")
seen := map[uint]string{}
for _, n := range names {
m, err := source.DefaultParse(n)
if err != nil {
continue
}
if prev, dup := seen[m.Version]; dup {
return fmt.Errorf("duplicate version %d: %s vs %s", m.Version, prev, n)
}
seen[m.Version] = n
} Try / catch
d, err := bindata.WithInstance(assetSource)
if err != nil && strings.HasPrefix(err.Error(), "unable to parse file") {
return fmt.Errorf("duplicate migration versions embedded in assets: %w", err)
} Prevention
- Regenerate the bindata bundle after every migration file change
- CI check: parse all embedded asset names and assert unique versions
- Exclude editor/backup files from embed patterns
When it happens
Trigger: WithInstance on an asset source whose embedded migration files contain two entries with the same version number.
Common situations: Regenerating go-bindata assets after adding a migration that reuses an existing version number; two branches each adding migrations with the same version before merging; copy-pasted filenames with different extensions (001_x.sql and 001_x.sql.bak both embedded).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse file %v
- unable to parse file %v
- database is dirty
- database is dirty
- unable to obtain lock
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/5df533e6e6686c79.
Report an issue: GitHub.