TencentCloud/TencentDB-Agent-Memory · error · MetadataError

last_system_admin

last_system_admin

Error message

cannot delete the last system_admin user

What it means

MetadataError 'last_system_admin' from deleteUsersForCaller: the batch would delete every remaining system_admin, leaving the system without admin governance. The service counts admins (countSystemAdmins) and refuses when totalAdmins - deletingSystemAdmins < 1.

Source

Thrown at MemoryCore/src/metadata/service/metadata-service.ts:526

    return this.store.getUserByKey(userKey);
  }

  async getUserByExternalId(authProvider: string, externalId: string): Promise<UserEntity | null> {
    return this.store.getUserByExternalId(authProvider, externalId);
  }

  async deleteUsersForCaller(userIds: string[], ctx: V3AuthContext): Promise<BatchDeleteResult> {
    if (!canManageUsers(ctx)) {
      throw new MetadataError("permission_denied", "user management requires system admin");
    }
    let deletingSystemAdmins = 0;
    for (const id of userIds) {
      const u = await this.getUserById(id);
      if (u && isSystemAdminUser(u)) deletingSystemAdmins++;
    }
    const totalAdmins = await this.store.countSystemAdmins();
    if (totalAdmins > 0 && totalAdmins - deletingSystemAdmins < 1) {
      throw new MetadataError("last_system_admin", "cannot delete the last system_admin user");
    }
    return this.deleteUsers(userIds);
  }

  async deleteUsers(userIds: string[]): Promise<BatchDeleteResult> {
    return this.store.deleteUsers(userIds);
  }

  async listUsersForCaller(
    input: { team_id?: string } & UserListFilter,
    ctx: V3AuthContext,
    pagination: PaginationParams,
  ): Promise<PaginatedResult<UserPublic>> {
    const filtersPresent = !!(input.user_ids?.length || input.username);
    const storeFilter = this.buildUserListStoreFilter(input);

    if (!input.team_id) {
      if (!ctx.isSystemAdmin) {

View on GitHub (pinned to 3efcd317b8)

Solutions

  1. Remove the system_admin id(s) from the deletion batch and keep at least one admin
  2. Promote another user to system_admin first, then delete the original
  3. Filter the batch: skip ids where isSystemAdminUser(u) is true when totalAdmins === 1

Example fix

// before
await svc.deleteUsersForCaller([adminId, u1, u2], ctx); // throws last_system_admin
// after
const deletable = [u1, u2]; // exclude the last system_admin
await svc.deleteUsersForCaller(deletable, ctx);
Defensive patterns

Strategy: validation

Validate before calling

const totalAdmins = await store.countSystemAdmins();
const adminDeletes = 0;
for (const id of userIds) {
  const u = await svc.getUserById(id);
  if (u && isSystemAdminUser(u)) adminDeletes++;
}
if (totalAdmins > 0 && totalAdmins - adminDeletes < 1) {
  throw new Error('batch would remove the last system_admin');
}

Type guard

function isDeletable(u: UserEntity | null, remainingAdmins: number): boolean {
  return !(u && isSystemAdminUser(u) && remainingAdmins - 1 < 1);
}

Try / catch

try {
  await svc.deleteUsersForCaller(ids, ctx);
} catch (e) {
  if (e instanceof MetadataError && e.code === 'last_system_admin') {
    // retry excluding admin ids
  } else throw e;
}

Prevention

When it happens

Trigger: Calling deleteUsersForCaller with a batch that includes the only existing system_admin (e.g. ['admin-id']), or a batch whose admin deletions exhaust the admin pool.

Common situations: Cleanup scripts bulk-deleting stale accounts that include the bootstrap admin; deleting 'test' users where the bootstrap admin was actually in use; multi-tenant scripts iterating all user ids.

Related errors


AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01). Data as JSON: /api/errors/b2131730a960b7cd. Report an issue: GitHub.