iflytek/astron-agent · error
mysql dsn is nil
Error message
mysql dsn is nil
What it means
ensureMySQLDatabase receives the parsed go-sql-driver *mysql.Config and guards against a nil pointer before it clones the DSN to run admin (database-creating) statements. A nil parsedDsn means the DSN parse step upstream produced no config object at all, so the function cannot proceed.
Solutions
- In buildMysql, check the error from mysql.ParseDSN before using the returned config and return the parse error instead of continuing.
- Ensure the DSN string built in parseMysqlConfig is non-empty and well-formed before parsing.
- Add a defensive nil check/log where the *mysql.Config originates so the nil never propagates.
- Write a unit test for buildMysql covering the empty-DSN path.
Example fix
// before
parsedDsn, _ := mysql.ParseDSN(dsn)
if err := ensureMySQLDatabase(parsedDsn); err != nil {
return nil, err
}
// after
parsedDsn, err := mysql.ParseDSN(dsn)
if err != nil {
return nil, fmt.Errorf("parse mysql dsn: %w", err)
}
if err := ensureMySQLDatabase(parsedDsn); err != nil {
return nil, err
} Defensive patterns
Strategy: type-guard
Validate before calling
if parsedDsn == nil {
return errors.New("mysql dsn parse failed before ensureMySQLDatabase")
} Type guard
func dsnConfigIsValid(c *mysql.Config) bool { return c != nil && c.DBName != "" } Try / catch
if err != nil {
return fmt.Errorf("build mysql: %w", err)
} Prevention
- Never discard errors from mysql.ParseDSN with _.
- Run go vet / errcheck so ignored errors are caught in CI.
- Write table-driven tests for DSN construction covering empty inputs.
When it happens
Trigger: buildMysql calls ensureMySQLDatabase with the result of mysql.ParseDSN when that call returned nil (typically alongside a parse error that was mishandled or an empty DSN input).
Common situations: Programmer error where the ParseDSN error is ignored and nil is passed through; refactoring that changed the DSN construction and dropped the error check; calling ensureMySQLDatabase directly in tests with no config.
Related errors
- mysql database name is empty
- mysql client is nil
- locked tenant bootstrap app does not match the reserved…
- reserved tenant bootstrap app is disabled or deleted
- tenant bootstrap API key is already assigned to another…
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/487a23974615d218.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/tools/database/database.go:114
credentials config.TenantBootstrapCredentials,
) error {
if err := runMigrations(client); err != nil {
return err
}
if err := reconcileTenantBootstrap(client, credentials); err != nil {
return err
}
log.Printf("tenant bootstrap credentials reconciled")
return nil
}
func (db *Database) GetMysql() *sql.DB {
return db.mysql
}
func ensureMySQLDatabase(parsedDsn *mysql.Config) error {
if parsedDsn == nil {
return errors.New("mysql dsn is nil")
}
if parsedDsn.DBName == "" {
return errors.New("mysql database name is empty")
}
adminDsn := parsedDsn.Clone()
dbName := adminDsn.DBName
adminDsn.DBName = ""
client, err := sql.Open("mysql", adminDsn.FormatDSN())
if err != nil {
return err
}
defer func() {
_ = client.Close()
}()
if err := client.Ping(); err != nil {View on GitHub (pinned to 5e758547a8)