{"record":{"id":"478420b4e8aa903b","repo":"iflytek/astron-agent","slug":"mysql-database-name-is-empty","errorCode":null,"errorMessage":"mysql database name is empty","messagePattern":"mysql database name is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/tools/database/database.go","lineNumber":117,"sourceCode":"\t\treturn err\n\t}\n\tif err := reconcileTenantBootstrap(client, credentials); err != nil {\n\t\treturn err\n\t}\n\tlog.Printf(\"tenant bootstrap credentials reconciled\")\n\treturn nil\n}\n\nfunc (db *Database) GetMysql() *sql.DB {\n\treturn db.mysql\n}\n\nfunc ensureMySQLDatabase(parsedDsn *mysql.Config) error {\n\tif parsedDsn == nil {\n\t\treturn errors.New(\"mysql dsn is nil\")\n\t}\n\tif parsedDsn.DBName == \"\" {\n\t\treturn errors.New(\"mysql database name is empty\")\n\t}\n\n\tadminDsn := parsedDsn.Clone()\n\tdbName := adminDsn.DBName\n\tadminDsn.DBName = \"\"\n\n\tclient, err := sql.Open(\"mysql\", adminDsn.FormatDSN())\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\t_ = client.Close()\n\t}()\n\n\tif err := client.Ping(); err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/tools/database/database.go#L99-L135","documentation":"ensureMySQLDatabase requires parsedDsn.DBName to be non-empty because it must connect to and create the target tenant database using an admin DSN (with DBName blanked). An empty DBName means the DSN string built from config did not include the database path component, so there is no database to ensure.","triggerScenarios":"The DSN passed to mysql.ParseDSN lacked the '/dbname' suffix — e.g. database.name in config is empty while url/user/password are set, or the fmt.Sprintf in parseMysqlConfig was edited to drop the database segment.","commonSituations":"Config file missing database.name; env var for the schema name unset; DSN constructed manually as 'user:pass@tcp(host:port)' without the trailing '/tenantdb'.","solutions":["Set the database name in the tenant config (or its env var) so the DSN ends with '/<dbname>'.","Verify the DSN format: 'user:pass@tcp(host:port)/dbname' — confirm the '/dbname' part survives to ParseDSN.","Re-run after checking parsedDsn.DBName via debug logging if unsure which segment was lost.","Add a startup validation that database.name is non-empty alongside url/username/password."],"exampleFix":"// before\ndsn := fmt.Sprintf(\"%s:%s@tcp%s\", user, pass, url)\n\n// after\ndsn := fmt.Sprintf(\"%s:%s@tcp%s/%s\", user, pass, url, conf.DataBase.DataBase)","handlingStrategy":"validation","validationCode":"if conf.DataBase.DataBase == \"\" {\n\treturn errors.New(\"database.name must be set so the DSN contains /<dbname>\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build DSNs as user:pass@tcp(host:port)/dbname and unit-test the format.","Require database.name alongside url/user/password in config validation.","Log a sanitized DSN (credentials redacted) at startup to verify the schema segment."],"tags":["mysql","dsn","config","go"],"backgroundTag":"empty-required-field","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}