{"record":{"id":"af4d8e726fceeebe","repo":"golang-migrate/migrate","slug":"unable-to-parse-file-v","errorCode":null,"errorMessage":"unable to parse file %v","messagePattern":"unable to parse file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"source/aws_s3/s3.go","lineNumber":94,"sourceCode":"}\n\nfunc (s *s3Driver) loadMigrations() error {\n\toutput, err := s.s3client.ListObjects(&s3.ListObjectsInput{\n\t\tBucket:    aws.String(s.config.Bucket),\n\t\tPrefix:    aws.String(s.config.Prefix),\n\t\tDelimiter: aws.String(\"/\"),\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, object := range output.Contents {\n\t\t_, fileName := path.Split(aws.StringValue(object.Key))\n\t\tm, err := source.DefaultParse(fileName)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif !s.migrations.Append(m) {\n\t\t\treturn fmt.Errorf(\"unable to parse file %v\", aws.StringValue(object.Key))\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *s3Driver) Close() error {\n\treturn nil\n}\n\nfunc (s *s3Driver) First() (uint, error) {\n\tv, ok := s.migrations.First()\n\tif !ok {\n\t\treturn 0, os.ErrNotExist\n\t}\n\treturn v, nil\n}\n\nfunc (s *s3Driver) Prev(version uint) (uint, error) {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/source/aws_s3/s3.go#L76-L112","documentation":"While listing S3 objects, loadMigrations parses each filename with source.DefaultParse. Files that don't look like migrations are silently skipped, but if a filename DOES parse and Append still fails — meaning another migration with the same version was already added (duplicate version) — the driver returns this error wrapping the full object key. Append only fails on duplicate versions, not parse errors.","triggerScenarios":"s3:// URL used with WithInstance where the bucket/prefix contains two objects whose basenames resolve to the same migration version, e.g. `1_foo.up.sql` in two folders within the prefix, or `1_foo.up.sql` and `001_bar.up.sql`.","commonSituations":"Bucket prefix overlapping nested directories (prefix `migrations/` also matching `migrations-old/` listing); copied/duplicated migration files; case-sensitivity mishaps creating near-duplicates; an old migration re-uploaded under a different name but same version.","solutions":["List objects under the S3 prefix and find the two keys sharing the same parsed version; delete or re-version one.","Narrow the S3 URL prefix (e.g. s3://bucket/migrations/current) so nested/legacy directories are not included in the listing.","Ensure version prefixes in filenames are unique across the bucket path, including zero-padding differences (1_ vs 001_).","Re-upload cleaned migration files and retry the migration."],"exampleFix":"// before\nmigrations/1_add_users.up.sql\nmigrations/archive/1_add_users.up.sql  // duplicate version under same prefix\n// after\nmigrations/1_add_users.up.sql\nmigrations/archive/2023_add_users.up.sql","handlingStrategy":"validation","validationCode":"// dedupe by parsed version before WithInstance\nseen := map[uint]bool{}\nfor _, key := range s3Keys {\n    _, fname := path.Split(key)\n    m, err := source.DefaultParse(fname)\n    if err != nil || m == nil {\n        continue\n    }\n    v := m.Version\n    if seen[v] {\n        return fmt.Errorf(\"duplicate version %d in s3 prefix: %s and earlier file\", v, key)\n    }\n    seen[v] = true\n}","typeGuard":null,"tryCatchPattern":"d, err := s3Source.WithInstance(ctx)\nif err != nil && strings.HasPrefix(err.Error(), \"unable to parse file\") {\n    key := strings.TrimPrefix(err.Error(), \"unable to parse file \")\n    // inspect/remove the duplicate object named by key, then retry\n    return fmt.Errorf(\"duplicate migration version for object %s\", key)\n}","preventionTips":["Use a precise S3 prefix that contains only the active migrations directory.","Keep zero-padded, unique version prefixes across the whole prefix (incl. nested folders).","Delete archived/duplicated migrations from the listed prefix.","Lint bucket contents in CI for duplicate parsed versions."],"tags":["aws","s3","migrations","duplicate"],"backgroundTag":"duplicate-migration-version","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}