iflytek/astron-agent · critical

mysql client is nil

Error message

mysql client is nil

What it means

runMigrations is the entry point for applying tenantInitStatements via a schema-migrations table. It throws 'mysql client is nil' when the *sql.DB handed to it is nil, meaning MySQL initialization failed earlier (or buildMysql returned a nil client) but execution continued into migrations.

Solutions

  1. Fix the upstream buildMysql/initializeMysqlClient error path so a failed MySQL build aborts startup instead of proceeding with nil.
  2. Check startup logs for the earlier MySQL error (empty url, bad DSN, connection refused) that produced the nil client.
  3. Ensure buildMysql returns (nil, err) and initializeMysqlClient checks err before calling runMigrations.
  4. Add an integration test that MySQL failure causes a fast, explicit startup failure.

Example fix

// before
client, err := buildMysql(conf)
if err != nil {
    log.Printf("mysql init failed: %v", err)
}
return runMigrations(client)

// after
client, err := buildMysql(conf)
if err != nil {
    return fmt.Errorf("build mysql client: %w", err)
}
return runMigrations(client)
Defensive patterns

Strategy: type-guard

Validate before calling

if client == nil {
	return errors.New("mysql client not initialized; aborting before migrations")
}

Type guard

func readyForMigrations(db *sql.DB) bool { return db != nil }

Try / catch

if err := initializeMysqlClient(cfg); err != nil {
	log.Fatalf("mysql init failed: %v", err)
}

Prevention

When it happens

Trigger: initializeMysqlClient calls runMigrations(db) where db is a nil *sql.DB — happens when buildMysql returned nil after an error that was swallowed, or initializeMysqlClient is invoked before MySQL configuration is available.

Common situations: MySQL init failed (bad DSN, unreachable server) but the error was logged-not-propagated; wiring change in server startup passed the zero-value Database; tests calling runMigrations(nil).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/c00b0a8a2953a361. Report an issue: GitHub.

Appendix: source

Thrown at core/tenant/tools/database/migrations.go:32

)

type migration struct {
	Version     string
	Description string
	Statements  []string
}

var migrations = []migration{
	{
		Version:     initVersion,
		Description: "init tenant tables and seed data",
		Statements:  tenantInitStatements,
	},
}

func runMigrations(client *sql.DB) error {
	if client == nil {
		return errors.New("mysql client is nil")
	}

	if err := ensureMigrationTable(client); err != nil {
		return err
	}

	unlock, err := acquireMigrationLock(client)
	if err != nil {
		return err
	}
	defer unlock()

	if err := stampLegacyDatabase(client); err != nil {
		return err
	}

	appliedVersions, err := loadAppliedVersions(client)
	if err != nil {

View on GitHub (pinned to 5e758547a8)