{"record":{"id":"7e15c220fcf9e0c9","repo":"golang-migrate/migrate","slug":"register-driver-is-nil","errorCode":null,"errorMessage":"Register driver is nil","messagePattern":"Register driver is nil","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"database/driver.go","lineNumber":106,"sourceCode":"\t\treturn nil, err\n\t}\n\n\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":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/driver.go#L88-L124","documentation":"database.Register panics (not an error return) when the driver argument is nil. The global driver registry stores database.Driver implementations by name, and a nil entry would cause nil-pointer panics later during Open, so it is rejected eagerly at registration time.","triggerScenarios":"Calling database.Register(\"mydb\", nil) directly, or registering a variable/interface that is nil due to failed initialization of a custom driver, often from a package's init().","commonSituations":"Custom database drivers registered in init() where construction failed silently; copied registration boilerplate with the driver left unset; import cycles causing partially initialized package variables.","solutions":["Ensure the Driver value is fully constructed before calling Register; construct it after all dependencies are ready.","Guard against import-cycle-induced nil package vars by moving registration to an explicit init function called from main.","Check the driver constructor for swallowed errors that leave a nil interface value."],"exampleFix":"// before\nfunc init() { database.Register(\"mydb\", drv) } // drv is nil on failure path\n// after\nfunc init() {\n\td, err := newDriver()\n\tif err != nil { panic(err) }\n\tdatabase.Register(\"mydb\", d)\n}","handlingStrategy":"validation","validationCode":"if driver == nil {\n\tpanic(\"refusing to call database.Register with nil driver\")\n}\ndatabase.Register(name, driver)","typeGuard":"func isNilDriver(d database.Driver) bool {\n\tif d == nil { return true }\n\treturn reflect.ValueOf(d).Kind() == reflect.Ptr && reflect.ValueOf(d).IsNil()\n}","tryCatchPattern":"// Register panics rather than returning error; isolate at startup:\nfunc mustRegister(name string, d database.Driver) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tlog.Fatalf(\"driver registration failed: %v\", r)\n\t\t}\n\t}()\n\tdatabase.Register(name, d)\n}","preventionTips":["Always construct drivers via constructors that return (Driver, error) and check the error.","Register drivers in a single explicit setup function instead of scattered init()s.","Write a smoke test that calls database.List() after setup and asserts your driver is present."],"tags":["go","migrate","panic","driver-registration","nil"],"backgroundTag":"nil-driver-registration-panic","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}