{"record":{"id":"84d7fa62bb957014","repo":"golang-migrate/migrate","slug":"register-called-twice-for-driver-84d7fa","errorCode":null,"errorMessage":"Register called twice for driver ","messagePattern":"Register called twice for driver ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"source/driver.go","lineNumber":104,"sourceCode":"\tdriversMu.RLock()\n\td, ok := drivers[u.Scheme]\n\tdriversMu.RUnlock()\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"source driver: unknown driver '%s' (forgotten import?)\", u.Scheme)\n\t}\n\n\treturn d.Open(url)\n}\n\n// Register globally registers a driver.\nfunc Register(name string, driver Driver) {\n\tdriversMu.Lock()\n\tdefer driversMu.Unlock()\n\tif driver == nil {\n\t\tpanic(\"Register driver is nil\")\n\t}\n\tif _, dup := drivers[name]; dup {\n\t\tpanic(\"Register called twice for driver \" + name)\n\t}\n\tdrivers[name] = driver\n}\n\n// List lists the registered drivers\nfunc List() []string {\n\tdriversMu.RLock()\n\tdefer driversMu.RUnlock()\n\tnames := make([]string, 0, len(drivers))\n\tfor n := range drivers {\n\t\tnames = append(names, n)\n\t}\n\treturn names\n}\n","sourceCodeStart":86,"sourceCodeEnd":119,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/source/driver.go#L86-L119","documentation":"source.Register panics when the given source driver name already exists in the global registry. Because most source drivers register themselves in init(), importing two packages that claim the same source name (or the same package under two module versions) causes the second Register to panic.","triggerScenarios":"Importing two source driver packages registering the same name, one module imported at two versions in go.mod, or a custom driver registered twice (e.g. once in tests, once in init).","commonSituations":"Forked copies of a source driver both imported, duplicate source names in custom drivers, test suites calling Register repeatedly without isolation.","solutions":["Deduplicate imports / consolidate module versions so the driver registers once.","Use a unique name for your custom source driver.","Wrap registration in sync.Once when it cannot live in init().","In tests, register distinct names per test case or construct drivers directly instead of registering."],"exampleFix":"// before\nsource.Register(\"s3\", d1)\nsource.Register(\"s3\", d2) // panic\n// after\nsource.Register(\"s3\", d1)\nsource.Register(\"s3-custom\", d2)","handlingStrategy":"validation","validationCode":"func registerSourceOnce(name string, d source.Driver) {\n\tfor _, n := range source.List() {\n\t\tif n == name {\n\t\t\treturn\n\t\t}\n\t}\n\tsource.Register(name, d)\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tif s, ok := r.(string); ok && strings.HasPrefix(s, \"Register called twice for driver\") {\n\t\t\tlog.Warnf(\"duplicate source driver: %s\", s)\n\t\t\treturn\n\t\t}\n\t\tpanic(r)\n\t}\n}()\nsource.Register(name, srcDrv)","preventionTips":["Verify go.mod doesn't pull two versions of the same source driver module (go mod graph).","Use unique names for every custom source driver.","Restrict Register calls to init() or a sync.Once-guarded setup.","Run go mod tidy and review imports when adding source driver packages."],"tags":["go","migrate","panic","driver-registration","duplicate"],"backgroundTag":"driver-registered-twice-panic","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}