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
- Re-enable the app: UPDATE tb_app SET is_disable=0, is_delete=0 WHERE app_id = <reserved tenant ID>
- Backfill NULL flag columns to 0 for the bootstrap app
- Investigate which admin operation/job disabled or deleted the reserved app and exclude reserved apps from it
- 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
- Exclude reserved bootstrap apps from admin disable/delete tooling
- Backfill is_disable/is_delete to NOT NULL DEFAULT 0
- Alert on state changes to reserved tenant rows
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
- locked tenant bootstrap app does not match the reserved…
- tenant bootstrap API key is already assigned to another…
- tenant bootstrap API key conflicts with an unmanaged…
- ensure tenant bootstrap app failed
- check tenant bootstrap API key ownership failed
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)