iflytek/astron-agent · error

reserved tenant bootstrap app is disabled or deleted

Error message

reserved tenant bootstrap app is disabled or deleted

What it means

After locking the bootstrap app row, this check fails if is_disable or is_delete is NULL (invalid) or true — i.e., the reserved tenant bootstrap app has been disabled or soft-deleted, so reconciliation cannot safely use it.

Solutions

  1. Re-enable the app: UPDATE tb_app SET is_disable=0, is_delete=0 WHERE app_id = <reserved tenant ID>
  2. Backfill NULL flag columns to 0 for the bootstrap app
  3. Investigate which admin operation/job disabled or deleted the reserved app and exclude reserved apps from it
  4. Re-run bootstrap reconciliation after restoring the row state

Example fix

// before
UPDATE tb_app SET is_disable = 1 WHERE app_id = 'reserved-tenant';
// after
UPDATE tb_app SET is_disable = 0, is_delete = 0 WHERE app_id = 'reserved-tenant';
Defensive patterns

Strategy: validation

Validate before calling

// preflight outside the transaction
var disabled, deleted sql.NullBool
_ = db.QueryRow(`SELECT is_disable, is_delete FROM tb_app WHERE app_id = ?`, tenantID).Scan(&disabled, &deleted)
if (disabled.Valid && disabled.Bool) || (deleted.Valid && deleted.Bool) { /* restore row before bootstrap */ }

Try / catch

if err != nil && strings.Contains(err.Error(), "disabled or deleted") { restoreReservedAppRow(db, tenantID); return reconcileBootstrap(ctx, creds) }

Prevention

When it happens

Trigger: tb_app row for the reserved tenant has is_disable=1, is_delete=1, or NULL values for either column when reconcileTenantBootstrapTransaction executes.

Common situations: Someone disabled or soft-deleted the bootstrap app via admin tooling; a migration left the flag columns NULL; soft-delete cleanup job removed the reserved app.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

	// Serialize reconciliation across replicas on the reserved app row before
	// taking any auth-index gap locks or rotating managed credentials.
	var lockedAppID string
	var lockedAppDisabled sql.NullBool
	var lockedAppDeleted sql.NullBool
	if err := transaction.QueryRowContext(
		ctx,
		`SELECT app_id, is_disable, is_delete FROM tb_app WHERE app_id = ? FOR UPDATE`,
		credentials.TenantID,
	).Scan(&lockedAppID, &lockedAppDisabled, &lockedAppDeleted); err != nil {
		return fmt.Errorf("lock tenant bootstrap app failed: %w", err)
	}
	if lockedAppID != credentials.TenantID {
		return errors.New("locked tenant bootstrap app does not match the reserved tenant ID")
	}
	if !lockedAppDisabled.Valid || lockedAppDisabled.Bool ||
		!lockedAppDeleted.Valid || lockedAppDeleted.Bool {
		return errors.New("reserved tenant bootstrap app is disabled or deleted")
	}
	return nil
}

func findTenantBootstrapCredential(
	ctx context.Context,
	transaction bootstrapTransaction,
	credentials config.TenantBootstrapCredentials,
) (bool, error) {
	var collisionOwner string
	err := transaction.QueryRowContext(
		ctx,
		`SELECT app_id
FROM tb_auth
WHERE api_key = ? AND app_id <> ? AND is_delete = 0
LIMIT 1 FOR UPDATE`,
		credentials.APIKey,
		credentials.TenantID,

View on GitHub (pinned to 5e758547a8)