Repairing user account database tables

I have a Nextcloud server that I’ve been hauling around since NC14 I think. Originally all users were local to NC, then for short-term project I set up LDAP and added a bunch of users, then when that project ended I disabled all of those users and switched off the LDAP backend. I keep up with major releases as best I can, so now the server is on the latest NC (28.0.3 for at least the next few minutes).

One feature of recent NC installs is that in the Administration Overview, there’s an item telling you about log errors. Which is handy! I haven’t been looking at the logs because everything seems to be behaving, but now I have a log warning every few minutes that the total user count is negative:

[support] Warning: Total user count was negative (users: 11, disabled: 12)
from ? by – at Mar 7, 2024, 1:30:02 AM

Sadly I do not know how long this has been going on. I disabled all of the LDAP user accounts about a year ago, maybe closer to 2 years, and I don’t recall this happening at that time.

Anyway - if I go to the Users interface, it shows the list of active users (9 users), but on the left sidebar, the “Active users” count shows -1.
If I go to Disabled users, which shows a count of 12, the listing is empty (“No users”) and there’s an error popup “An error occurred during the request. Unable to proceed.” There’s no new entry in the log though.

I assume the issue here is that the old LDAP user accounts are still hanging out somewhere, but the nextcloud database doesn’t exactly lend itself to manual edits. I tried to understand how user accounts are stored in the database but got as far as User data and the database schema where the answer is basically “It’s complicated.”

What I see in the database:
oc_accounts: every user that has ever existed on the system, with a wad of JSON for each one
oc_accounts_data: empty
oc_known_users: empty
oc_ldap_user_mapping: every LDAP user that ever existed
oc_user_status: a list of 9 users, which is coincidentally the number of active users, but it’s not a list of the active users: it’s got 5 local database users, one of which is not an active user, 4 active users, and 4 LDAP users
oc_users: a list of every local database user, including 2 which are disabled
oc_users_external: empty
oc_preferences: >1000 rows of data, which appear to account for every user ever on the system (anywhere from 13 - 200+ rows per user)

So based on the discussion in the thread linked above, it seems like the most likely offense is in the oc_preferences table.

Hunting around a bit, I found
which seems to be helpful? If I run the “ldap:show-remnants” command it proposes, I get a list of all of the old LDAP users, but if I try the “user:delete” command on any of them (using the “Nextcloud name” field) it just says “User does not exist.”

Given that the LDAP users are all gone, and there’s no useful data stored in those account areas now: is it safe to delete entries from oc_preferences and then hunt those UUIDs down in the other tables and delete them too?