From 8c457912c403a2afab625d2e2a53729f1348f69e Mon Sep 17 00:00:00 2001 From: Jvst Me Date: Wed, 24 Dec 2025 10:05:38 +0100 Subject: [PATCH] Allow users to delete their only project The restriction preventing users from deleting their only project was originally introduced because the UI could not function correctly without projects, which is no longer the case. --- src/dstack/_internal/server/services/projects.py | 2 -- src/tests/_internal/server/routers/test_projects.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dstack/_internal/server/services/projects.py b/src/dstack/_internal/server/services/projects.py index 5e4842df56..fef7e5faaf 100644 --- a/src/dstack/_internal/server/services/projects.py +++ b/src/dstack/_internal/server/services/projects.py @@ -199,8 +199,6 @@ async def delete_projects( for project in projects_to_delete: if not _is_project_admin(user=user, project=project): raise ForbiddenError() - if all(name in projects_names for name in user_project_names): - raise ServerClientError("Cannot delete the only project") res = await session.execute( select(ProjectModel) diff --git a/src/tests/_internal/server/routers/test_projects.py b/src/tests/_internal/server/routers/test_projects.py index 826ecbc096..4b62ac416d 100644 --- a/src/tests/_internal/server/routers/test_projects.py +++ b/src/tests/_internal/server/routers/test_projects.py @@ -453,7 +453,7 @@ async def test_returns_40x_if_not_authenticated(self, test_db, client: AsyncClie @pytest.mark.asyncio @pytest.mark.parametrize("test_db", ["sqlite", "postgres"], indirect=True) - async def test_cannot_delete_the_only_project( + async def test_deletes_the_only_project( self, test_db, session: AsyncSession, client: AsyncClient ): user = await create_user(session=session, global_role=GlobalRole.USER) @@ -466,9 +466,9 @@ async def test_cannot_delete_the_only_project( headers=get_auth_headers(user.token), json={"projects_names": [project.name]}, ) - assert response.status_code == 400 + assert response.status_code == 200 await session.refresh(project) - assert not project.deleted + assert project.deleted @pytest.mark.asyncio @pytest.mark.parametrize("test_db", ["sqlite", "postgres"], indirect=True)