Bug Description
deleteApplicationResources performs six sequential async operations to archive an application's resources. A TransactionalOperator is injected into the class but never applied to this chain. If the server is killed between any two steps, the application enters a permanently broken state: some resources are deleted, the application document still exists, but the remaining resources are gone.
Affected file
�pp/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java:
Field declared at line 131:
java private final TransactionalOperator transactionalOperator;
Delete chain at lines 579-72 with no .as(transactionalOperator::transactional):
java protected Mono<Application> deleteApplicationResources(Application application) { return actionPermissionMono .flatMap(...actionCollectionService.archiveActionCollectionByApplicationId(...)) .then(...newActionService.archiveActionsByApplicationId(...)) .then(...newPageService.archivePagesByApplicationId(...)) .then(themeService.archiveApplicationThemes(application)) .then(userDataService.removeApplicationFromAllFavorites(...)) .then(applicationService.archive(application)); // step 6 - may never run }
For contrast, ImportServiceCEImpl.java:552 correctly uses .as(transactionalOperator::transactional).
Failure scenario
- User deletes an application with 50 pages and 200 actions.
- Steps 1-4 complete: action collections, actions, pages, themes all archived.
- Server receives SIGTERM during step 5 or 6.
- �pplicationService.archive(application) never runs.
- The application document remains in MongoDB, visible in the workspace list.
- Opening the application fails (no pages/actions). Attempting to delete again partially succeeds but leaves the document stuck since steps 1-4 are now no-ops.
- The application is permanently a "ghost" record that cannot be opened or deleted.
Fix
Apply the injected operator to the delete chain:
java protected Mono<Application> deleteApplicationResources(Application application) { return actionPermissionMono .flatMap(...) ... .then(applicationService.archive(application)) .as(transactionalOperator::transactional); }
Environment
Appsmith elease branch (2026-08-13), Java/Spring WebFlux, MongoDB.
Bug Description
deleteApplicationResources performs six sequential async operations to archive an application's resources. A TransactionalOperator is injected into the class but never applied to this chain. If the server is killed between any two steps, the application enters a permanently broken state: some resources are deleted, the application document still exists, but the remaining resources are gone.
Affected file
�pp/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java:
Field declared at line 131:
java private final TransactionalOperator transactionalOperator;Delete chain at lines 579-72 with no .as(transactionalOperator::transactional):
java protected Mono<Application> deleteApplicationResources(Application application) { return actionPermissionMono .flatMap(...actionCollectionService.archiveActionCollectionByApplicationId(...)) .then(...newActionService.archiveActionsByApplicationId(...)) .then(...newPageService.archivePagesByApplicationId(...)) .then(themeService.archiveApplicationThemes(application)) .then(userDataService.removeApplicationFromAllFavorites(...)) .then(applicationService.archive(application)); // step 6 - may never run }For contrast, ImportServiceCEImpl.java:552 correctly uses .as(transactionalOperator::transactional).
Failure scenario
Fix
Apply the injected operator to the delete chain:
java protected Mono<Application> deleteApplicationResources(Application application) { return actionPermissionMono .flatMap(...) ... .then(applicationService.archive(application)) .as(transactionalOperator::transactional); }Environment
Appsmith elease branch (2026-08-13), Java/Spring WebFlux, MongoDB.