You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Deleting a user who has updated their own profile fails with CircularDependencyError #44865
A user who has updated their own profile through PUT /api/v1/me/ (name or password) can no longer be deleted. The delete fails until some other user edits them.
To reproduce (clean 6.1.0, Postgres metadata database, default config):
As an admin, create a user with any role (Gamma is enough).
Log in as that user and change the first name: PUT /api/v1/me/ with {"first_name": "Changed"}. It answers 200.
As the admin, delete the user from Settings → List Users, or DELETE /api/v1/security/users/<id>.
Expected: the user is deleted.
Actual: the API answers 422:
{"message": "Database exception occurred: Circular dependency detected. (DeleteState(<User at 0x...>))"}
The user list shows only "There was an issue deleting ". The server log has sqlalchemy.exc.CircularDependencyError.
The same happens to an admin who edits their own row with PUT /api/v1/security/users/<own id>. A user who has logged in but never edited themselves deletes fine.
Workaround: have an admin make any edit to the user (deactivating them, for example), then delete. The delete then answers 200.
Cause, as far as I can tell:
CurrentUserRestApi.pre_update (superset/views/users/api.py) sets item.changed_by_fk = g.user.id, so after a self-edit the row's changed_by_fk is its own id. The PUT on /api/v1/me/ arrived in 6.0.0 (feat(UserInfo): Migrate User Info FAB to React #33620).
Flask-AppBuilder's User model (flask_appbuilder/security/sqla/models.py) declares created_by and changed_by as self-referential relationships without post_update=True. SQLAlchemy's unit of work cannot order the delete of a row whose foreign key points at itself, and raises CircularDependencyError.
An admin edit cures it because FAB's UserApi.pre_update moves changed_by_fk to the admin.
4.1.1 does not show it for self-service: resetting your own password there never writes changed_by_fk.
Possible fixes: leave changed_by_fk alone (or null it) when a user edits themselves, null a self-referencing changed_by_fk in SupersetUserApi.pre_delete, or add post_update=True to the two relationships in Flask-AppBuilder.
The User relationships are the same on Flask-AppBuilder master, and master here still has the changed_by_fk = g.user.id line, so I expect it reproduces there too. I have not run master.
Hi @VirtualDylan! I'm Dosu and I'm helping the Apache Superset team.
Your diagnosis checks out against current master. CurrentUserRestApi.pre_update sets item.changed_by_fk = g.user.id on every self-edit through PUT /api/v1/me/ and never checks whether the editor is the same row [1].
Superset already works around FK issues on user deletion. SupersetUserApi overrides FAB's pre_delete to clear item.roles = [] before the delete, because otherwise the role association would block it [2]. That override has no handling for changed_by_fk/created_by_fk, so a self-referencing row still trips SQLAlchemy's circular dependency check on delete. Nulling a self-referencing changed_by_fk/created_by_fk there would follow the same pattern without touching Flask-AppBuilder.
I didn't find any existing issue, PR, or prior conversation that addresses this.
Bug description
A user who has updated their own profile through
PUT /api/v1/me/(name or password) can no longer be deleted. The delete fails until some other user edits them.To reproduce (clean 6.1.0, Postgres metadata database, default config):
PUT /api/v1/me/with{"first_name": "Changed"}. It answers 200.DELETE /api/v1/security/users/<id>.Expected: the user is deleted.
Actual: the API answers 422:
{"message": "Database exception occurred: Circular dependency detected. (DeleteState(<User at 0x...>))"}The user list shows only "There was an issue deleting ". The server log has
sqlalchemy.exc.CircularDependencyError.The same happens to an admin who edits their own row with
PUT /api/v1/security/users/<own id>. A user who has logged in but never edited themselves deletes fine.Workaround: have an admin make any edit to the user (deactivating them, for example), then delete. The delete then answers 200.
Cause, as far as I can tell:
CurrentUserRestApi.pre_update(superset/views/users/api.py) setsitem.changed_by_fk = g.user.id, so after a self-edit the row'schanged_by_fkis its ownid. ThePUTon/api/v1/me/arrived in 6.0.0 (feat(UserInfo): Migrate User Info FAB to React #33620).Usermodel (flask_appbuilder/security/sqla/models.py) declarescreated_byandchanged_byas self-referential relationships withoutpost_update=True. SQLAlchemy's unit of work cannot order the delete of a row whose foreign key points at itself, and raisesCircularDependencyError.UserApi.pre_updatemoveschanged_by_fkto the admin.4.1.1 does not show it for self-service: resetting your own password there never writes
changed_by_fk.Possible fixes: leave
changed_by_fkalone (or null it) when a user edits themselves, null a self-referencingchanged_by_fkinSupersetUserApi.pre_delete, or addpost_update=Trueto the two relationships in Flask-AppBuilder.Screenshots/recordings
No response
Superset version
6.1.0
Python version
3.11
Node version
Not applicable
Browser
Chrome
Additional context
apache/superset:6.1.0-py311, pluspsycopg2-binary. Flask-AppBuilder 5.0.2, SQLAlchemy 1.4.54, Postgres 16 metadata database.Userrelationships are the same on Flask-AppBuilder master, andmasterhere still has thechanged_by_fk = g.user.idline, so I expect it reproduces there too. I have not run master.CircularDependencyErrorandchanged_by_fkand found no existing report. A 2022 comment on cannot delete user "Associated data exists, please delete them first" #13345 mentions the same exception without a cause.Checklist