golang-migrate/migrate · error

unable to parse file %v

Error message

unable to parse file %v

What it means

Raised in Github.readDirectory when source.DefaultParse succeeds on a filename but g.migrations.Append rejects it — almost always a duplicate migration version (same version number already appended). The message includes the offending filename.

Source

Thrown at source/github/github.go:130

		g.config.Repo,
		g.config.Path,
		g.options,
	)

	if err != nil {
		return err
	}
	if fileContent != nil {
		return ErrNoDir
	}

	for _, fi := range dirContents {
		m, err := source.DefaultParse(*fi.Name)
		if err != nil {
			continue // ignore files that we can't parse
		}
		if !g.migrations.Append(m) {
			return fmt.Errorf("unable to parse file %v", *fi.Name)
		}
	}

	return nil
}

func (g *Github) ensureFields() {
	if g.config == nil {
		g.config = &Config{}
	}
}

func (g *Github) Close() error {
	return nil
}

func (g *Github) First() (version uint, err error) {
	g.ensureFields()

View on GitHub (pinned to 01a9643f14)

Solutions

  1. Rename the duplicate file so it has a unique version number (e.g. 0002_...)
  2. Check the target directory on the configured ref for two files sharing a version prefix
  3. Ensure only one migrations directory is being read (avoid overlapping Path entries)

Example fix

// before
0001_create_users.up.sql
0001_create_users.up.sql   // duplicate version 1
// after
0001_create_users.up.sql
0002_create_users.up.sql   // unique version
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight: detect duplicate versions locally before pushing migrations
seen := map[uint]struct{}{}
for _, name := range filenames {
    m, err := source.DefaultParse(name)
    if err != nil {
        continue
    }
    if _, dup := seen[m.Version]; dup {
        return fmt.Errorf("duplicate migration version %d in %s", m.Version, name)
    }
    seen[m.Version] = struct{}{}
}

Try / catch

d, err := source.Open(srcURL)
if err != nil {
    if strings.Contains(err.Error(), "unable to parse file") {
        return fmt.Errorf("duplicate migration version in repo directory: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Two files in the GitHub directory resolve to the same version, e.g. '0001_init.up.sql' and '0001_init.up.sql' across folders folded into one path, or '1_fix.sql' and '0001_fix.sql' both parsing to version 1.

Common situations: Reused version numbers after copying migration files between branches/environments; case-sensitivity or formatting differences creating near-duplicates; files with same numeric prefix but different direction/name.

Understand the failure class

Related errors


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