{"record":{"id":"419573ec9cd7dd9c","repo":"golang-migrate/migrate","slug":"unable-to-parse-file-v-419573","errorCode":null,"errorMessage":"unable to parse file %v","messagePattern":"unable to parse file (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"source/github/github.go","lineNumber":130,"sourceCode":"\t\tg.config.Repo,\n\t\tg.config.Path,\n\t\tg.options,\n\t)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\tif fileContent != nil {\n\t\treturn ErrNoDir\n\t}\n\n\tfor _, fi := range dirContents {\n\t\tm, err := source.DefaultParse(*fi.Name)\n\t\tif err != nil {\n\t\t\tcontinue // ignore files that we can't parse\n\t\t}\n\t\tif !g.migrations.Append(m) {\n\t\t\treturn fmt.Errorf(\"unable to parse file %v\", *fi.Name)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (g *Github) ensureFields() {\n\tif g.config == nil {\n\t\tg.config = &Config{}\n\t}\n}\n\nfunc (g *Github) Close() error {\n\treturn nil\n}\n\nfunc (g *Github) First() (version uint, err error) {\n\tg.ensureFields()","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/source/github/github.go#L112-L148","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rename the duplicate file so it has a unique version number (e.g. 0002_...)","Check the target directory on the configured ref for two files sharing a version prefix","Ensure only one migrations directory is being read (avoid overlapping Path entries)"],"exampleFix":"// before\n0001_create_users.up.sql\n0001_create_users.up.sql   // duplicate version 1\n// after\n0001_create_users.up.sql\n0002_create_users.up.sql   // unique version","handlingStrategy":"validation","validationCode":"// pre-flight: detect duplicate versions locally before pushing migrations\nseen := map[uint]struct{}{}\nfor _, name := range filenames {\n    m, err := source.DefaultParse(name)\n    if err != nil {\n        continue\n    }\n    if _, dup := seen[m.Version]; dup {\n        return fmt.Errorf(\"duplicate migration version %d in %s\", m.Version, name)\n    }\n    seen[m.Version] = struct{}{}\n}","typeGuard":null,"tryCatchPattern":"d, err := source.Open(srcURL)\nif err != nil {\n    if strings.Contains(err.Error(), \"unable to parse file\") {\n        return fmt.Errorf(\"duplicate migration version in repo directory: %w\", err)\n    }\n    return err\n}","preventionTips":["Enforce unique version prefixes in CI before merging migration PRs","Never copy old migration files into a directory that already has that version","Use a naming convention like NNNN_description.up.sql with monotonic numbers"],"tags":["github","migrations","duplicate-version"],"backgroundTag":"duplicate-migration-version","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}