DELETE /api/user/{username} crashes with 500 when the deleting admin has no DB-backed Admin row, even though the deletion succeeds
Describe the bug
Calling DELETE /api/user/{username} correctly removes the user from the database, but the request still returns HTTP 500 to the caller -- making it look like the deletion failed when it actually succeeded.
Root cause
In app/routers/user.py, the remove_user endpoint:
crud.remove_user(db, dbuser)
bg.add_task(xray.operations.remove_user, dbuser=dbuser)
bg.add_task(
report.user_deleted, username=dbuser.username, user_admin=Admin.model_validate(dbuser.admin), by=admin
)Admin.model_validate(dbuser.admin) is evaluated synchronously, while building the arguments for bg.add_task(...) -- it's not deferred into the background task. If dbuser.admin is None, this raises a Pydantic ValidationError inside the request, after the deletion has already committed.
How to reproduce
dbuser.admin is None when the user was created by the env-var-based sudo admin (SUDO_USERNAME/SUDO_PASSWORD in .env), which has no corresponding row in the admins table (confirm via GET /api/admins returning []).
- Set
SUDO_USERNAME/SUDO_PASSWORDin.env, with zero rows in theadminstable. - Authenticate as that sudo admin, create a user.
DELETE /api/user/{username}-> HTTP 500,pydantic_core._pydantic_core.ValidationError: 1 validation error for Admin ... input_value=None.GET /api/user/{username}-> 404. The user is actually gone.
Expected behavior
Either skip the report task when dbuser.admin is None, or guard the Admin.model_validate() call, and return a clean 200/204 since the deletion itself succeeded.
Environment
- Marzban version: 0.8.4 (latest release, also reproduced on current
master) - Confirmed via Docker logs and direct API testing
Source: Gozargah/Marzban