iflytek/astron-agent · critical

invalid tenant bootstrap credentials

Error message

invalid tenant bootstrap credentials: %w

What it means

reconcileTenantBootstrap validates the configured tenant bootstrap credentials (TenantBootstrapCredentials.Validate) before touching the database; invalid values abort with this wrapped error. It is a startup-time config guard ensuring the reserved tenant app/credentials are coherent before any SQL runs.

Solutions

  1. Run credentials.Validate() logic mentally against your config: fill in the missing/invalid field reported by the wrapped %w error.
  2. Fix the bootstrap env/config entries (tenant ID, API key, API secret) in the deployment manifest and restart the service.
  3. Read the wrapped inner error (errors.Unwrap / %v of the chain) — it names exactly which field failed validation.
  4. Add a config preflight check at startup that fails fast with the field name before opening the DB.

Example fix

// before
creds := config.TenantBootstrapCredentials{TenantID: cfg.TenantID} // key/secret empty
reconcileTenantBootstrap(client, creds)
// after
creds := config.TenantBootstrapCredentials{
    TenantID: cfg.TenantID,
    APIKey:   cfg.APIKey,
    APISecret: cfg.APISecret,
}
if err := creds.Validate(); err != nil {
    log.Fatalf("bootstrap config invalid: %v", err)
}
reconcileTenantBootstrap(client, creds)
Defensive patterns

Strategy: validation

Validate before calling

creds := config.TenantBootstrapCredentials{TenantID: os.Getenv("TENANT_ID"), APIKey: os.Getenv("TENANT_API_KEY"), APISecret: os.Getenv("TENANT_API_SECRET")}
if err := creds.Validate(); err != nil {
    log.Fatalf("tenant bootstrap config invalid: %v", err)
}

Type guard

func credsReady(c config.TenantBootstrapCredentials) bool {
    return c.TenantID != "" && c.APIKey != "" && c.APISecret != ""
}

Try / catch

if err := reconcileTenantBootstrap(client, creds); err != nil {
    var cfgErr *fmt.wrapError
    if errors.As(err, &cfgErr) && strings.HasPrefix(err.Error(), "invalid tenant bootstrap credentials") {
        log.Fatalf("fix TENANT_* env vars: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: initializeMysqlClient calls reconcileTenantBootstrap with credentials whose Validate() fails — e.g. missing TenantID, empty API key/secret, or malformed values in config/env.

Common situations: TENANT bootstrap env vars omitted or left empty in docker-compose/K8s manifests; secret contains whitespace or wrong length after templating; config struct partially populated because a YAML key was misnamed.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at core/tenant/tools/database/bootstrap_credentials.go:53

}

func (transaction sqlBootstrapTransaction) QueryRowContext(
	ctx context.Context,
	query string,
	args ...any,
) bootstrapRowScanner {
	return transaction.transaction.QueryRowContext(ctx, query, args...)
}

func reconcileTenantBootstrap(
	client *sql.DB,
	credentials config.TenantBootstrapCredentials,
) error {
	if client == nil {
		return errors.New("mysql client is nil")
	}
	if err := credentials.Validate(); err != nil {
		return fmt.Errorf("invalid tenant bootstrap credentials: %w", err)
	}

	ctx := context.Background()
	transaction, err := client.BeginTx(ctx, nil)
	if err != nil {
		return fmt.Errorf("begin tenant bootstrap transaction failed: %w", err)
	}
	defer func() {
		_ = transaction.Rollback()
	}()

	if err := reconcileTenantBootstrapTransaction(
		ctx,
		sqlBootstrapTransaction{transaction: transaction},
		credentials,
	); err != nil {
		return err
	}

View on GitHub (pinned to 5e758547a8)