golang-migrate/migrate · error
unable to parse file %v
Error message
unable to parse file %v
What it means
readDirectory parses each file returned by the Bitbucket ListFiles API with source.DefaultParse. Unparseable names are skipped, but if a name parses and migrations.Append still returns false — which only happens when another migration with the same version was already appended — the driver aborts with 'unable to parse file %v'. Despite the wording, the actual cause is a duplicate migration version, not a parse failure.
Source
Thrown at source/bitbucket/bitbucket.go:116
RepoSlug: b.config.Repo,
Ref: b.config.Ref,
Path: b.config.Path,
}
dirContents, err := b.client.Repositories.Repository.ListFiles(fOpt)
if err != nil {
return err
}
for _, fi := range dirContents {
m, err := source.DefaultParse(filepath.Base(fi.Path))
if err != nil {
continue // ignore files that we can't parse
}
if !b.migrations.Append(m) {
return fmt.Errorf("unable to parse file %v", fi.Path)
}
}
return nil
}
func (b *Bitbucket) ensureFields() {
if b.config == nil {
b.config = &Config{}
}
}
func (b *Bitbucket) Close() error {
return nil
}
func (b *Bitbucket) First() (version uint, er error) {
b.ensureFields()View on GitHub (pinned to 01a9643f14)
Solutions
- Find the duplicate version: list repo files and compute version prefixes; rename or delete one of the colliding migrations.
- Standardize on zero-padded seq prefixes (e.g. 000001_) so `1_` and `001_` no longer collide after parsing.
- Use `migrate create` for every new migration so versions are generated uniquely instead of hand-written.
- Fix the branch history (rebase/dedupe) if the same migration was merged twice, then retry.
Example fix
// before migrations/1_add_users.up.sql migrations/001_add_users_v2.up.sql // same parsed version 1 // after migrations/000001_add_users.up.sql migrations/000002_add_users_v2.up.sql
Defensive patterns
Strategy: validation
Validate before calling
// fetch file list and check for duplicate versions before WithInstance
seen := map[uint64]string{}
for _, fi := range dirContents {
m, err := source.DefaultParse(filepath.Base(fi.Path))
if err != nil {
continue
}
if prev, dup := seen[m.Version]; dup {
return fmt.Errorf("duplicate version %d: %s and %s", m.Version, prev, fi.Path)
}
seen[m.Version] = fi.Path
} Try / catch
d, err := bitbucket.WithInstance(cl, cfg)
if err != nil && strings.HasPrefix(err.Error(), "unable to parse file") {
f := strings.TrimPrefix(err.Error(), "unable to parse file ")
return fmt.Errorf("duplicate migration version detected for %s; dedupe and retry", f)
} Prevention
- Always create migrations with `migrate create` to get unique versions.
- Use zero-padded seq prefixes consistently (000001_).
- Check PR diffs for duplicate version prefixes in CI.
- Rebase/dedupe branches before merging the same migration twice.
When it happens
Trigger: bitbucket.WithInstance/Open where the repo listing contains two files whose basenames yield the same version, e.g. `1_foo.up.sql` and `001_bar.up.sql`, or the same filename present via path casing differences.
Common situations: Zero-padding inconsistencies between team members' created migrations; a migration cherry-picked or merged twice from branches; renamed file keeping an old version prefix.
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
- duplicate migration version: %s
- next sequence number %s too large, at most %d digits are all
- unable to parse file %v
- no directory
- database is dirty
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/841bdf83d517fa24.
Report an issue: GitHub.