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

  1. List the embedded asset names and find files resolving to the same version number
  2. Rename the duplicate to a unique, higher version number
  3. Regenerate the bindata asset bundle after renaming so stale entries are removed
  4. 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

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

Related errors


AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02). Data as JSON: /api/errors/5df533e6e6686c79. Report an issue: GitHub.