{"record":{"id":"eb7a058981cf8ef2","repo":"golang-migrate/migrate","slug":"register-called-twice-for-driver","errorCode":null,"errorMessage":"Register called twice for driver ","messagePattern":"Register called twice for driver ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"database/driver.go","lineNumber":109,"sourceCode":"\tdriversMu.RLock()\n\td, ok := drivers[scheme]\n\tdriversMu.RUnlock()\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"database driver: unknown driver %v (forgotten import?)\", 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":91,"sourceCodeEnd":124,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/driver.go#L91-L124","documentation":"database.Register panics if a driver with the same name was already registered in the global registry. This prevents silent driver shadowing; drivers are typically registered in package init(), so importing two packages that both register the same name triggers this.","triggerScenarios":"Importing two driver packages that both call database.Register(\"postgres\", ...), importing a driver package twice under different module versions, or registering the same custom driver name more than once (e.g. in tests).","commonSituations":"Duplicate driver names across vendored forks, TestRegisterTwice-style tests confirming the panic, a plugin registering on each reconnection instead of once, or two custom drivers accidentally given the same name.","solutions":["Remove or deduplicate the imports causing double registration (check go.mod for two versions of the same driver module).","Give your custom driver a unique registration name.","Ensure registration code runs exactly once (guard with sync.Once if not in init()).","If you must replace a driver, call database.Open with an explicit driver instance rather than re-registering."],"exampleFix":"// before\nimport _ \"github.com/x/mypostgres\" // registers \"postgres\"\nimport _ \"github.com/y/mypostgres\" // also registers \"postgres\" -> panic\n// after\nimport _ \"github.com/x/mypostgres\" // keep only one postgres driver import","handlingStrategy":"validation","validationCode":"// guard custom registration against duplicates\nfunc registerOnce(name string, d database.Driver) {\n\tfor _, existing := range database.List() {\n\t\tif existing == name {\n\t\t\treturn // already registered\n\t\t}\n\t}\n\tdatabase.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(\"ignoring duplicate driver registration: %s\", s)\n\t\t\treturn\n\t\t}\n\t\tpanic(r)\n\t}\n}()\ndatabase.Register(name, driver)","preventionTips":["Keep exactly one import of each database driver package in go.mod (no duplicate versions).","Give custom drivers unique, prefixed names (e.g. \"myapp-postgres\").","Never register drivers outside init()/one-time setup; use sync.Once for idempotency.","Before adding a driver import, grep the codebase for existing Register calls with that name."],"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"}