{"record":{"id":"dabe3e5475d3d6a1","repo":"go-sql-driver/mysql","slug":"logger-is-nil","errorCode":null,"errorMessage":"logger is nil","messagePattern":"logger is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"errors.go","lineNumber":57,"sourceCode":"\nvar defaultLogger = Logger(log.New(os.Stderr, \"[mysql] \", log.Ldate|log.Ltime))\n\n// Logger is used to log critical error messages.\ntype Logger interface {\n\tPrint(v ...any)\n}\n\n// NopLogger is a nop implementation of the Logger interface.\ntype NopLogger struct{}\n\n// Print implements Logger interface.\nfunc (nl *NopLogger) Print(_ ...any) {}\n\n// SetLogger is used to set the default logger for critical errors.\n// The initial logger is os.Stderr.\nfunc SetLogger(logger Logger) error {\n\tif logger == nil {\n\t\treturn errors.New(\"logger is nil\")\n\t}\n\tdefaultLogger = logger\n\treturn nil\n}\n\n// MySQLError is an error type which represents a single MySQL error\ntype MySQLError struct {\n\tNumber   uint16\n\tSQLState [5]byte\n\tMessage  string\n}\n\nfunc (me *MySQLError) Error() string {\n\tif me.SQLState != [5]byte{} {\n\t\treturn fmt.Sprintf(\"Error %d (%s): %s\", me.Number, me.SQLState, me.Message)\n\t}\n\n\treturn fmt.Sprintf(\"Error %d: %s\", me.Number, me.Message)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/03d76c7e07908e255ce62d126d07ede3f2365d86/errors.go#L39-L75","documentation":"Returned by SetLogger (errors.go:57) when the caller passes nil. The package keeps a non-nil defaultLogger (os.Stderr) and refuses to replace it with nothing, because a nil logger would panic on the next critical-error log call.","triggerScenarios":"Calling mysql.SetLogger(nil), or passing a logger variable that was never initialized (defaults to nil interface).","commonSituations":"Conditionally configuring logging (e.g. only when a flag is set) and falling through to SetLogger(nil); refactoring that accidentally drops the logger assignment.","solutions":["Pass a concrete logger: the standard logger, a structured logger adapter, or mysql.NopLogger to silence output.","Guard the call: only invoke SetLogger when your logger instance is non-nil.","To disable logging deliberately, use mysql.SetLogger(mysql.NopLogger{}) instead of nil."],"exampleFix":"// before\nif logOut != nil {\n    mysql.SetLogger(logOut)\n} else {\n    mysql.SetLogger(nil) // -> \"logger is nil\"\n}\n\n// after\nif logOut != nil {\n    mysql.SetLogger(logOut)\n} else {\n    mysql.SetLogger(mysql.NopLogger{})\n}","handlingStrategy":"validation","validationCode":"// Never pass nil; choose a real logger or the no-op one.\nvar l mysql.Logger = mysql.NopLogger{}\nif appLogger != nil {\n    l = appLogger // implements mysql.Logger\n}\nif err := mysql.SetLogger(l); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"if err := mysql.SetLogger(candidate); err != nil {\n    if err.Error() == \"logger is nil\" {\n        // pass mysql.NopLogger{} or a real logger instead\n    }\n}","preventionTips":["Use mysql.NopLogger{} to silence logging rather than nil.","Guard SetLogger calls behind a non-nil check.","Adapt your logger to the mysql.Logger interface (Print(...any))."],"tags":["logging","config","programming-error"],"backgroundTag":null,"analyzedSha":"03d76c7e07908e255ce62d126d07ede3f2365d86","analyzedAt":"2026-08-07T10:39:17.340Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}