Thanks to visit codestin.com
Credit goes to github.com

Skip to content

snapshot: deleteAllByApplicationId and createSnapshots not wrapped in transaction - server crash leaves application with no snapshot #42115

Description

@harsh4vardhan

Bug Description

createApplicationSnapshot calls deleteAllByApplicationId to remove all existing snapshot chunks, then calls createSnapshots to write the new ones. There is no transaction wrapping these two operations. If the server crashes or the MongoDB connection drops after the delete completes but before createSnapshots finishes, the application has no valid snapshot at all.

Affected file

�pp/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCEImpl.java, lines 44-50:

java .flatMapMany(artifactExchangeJson -> { return applicationSnapshotRepository .deleteAllByApplicationId(branchedApplicationId) // (1) old snapshot destroyed .thenMany(createSnapshots(branchedApplicationId, applicationJson)); // (2) new snapshot written }) // no .as(transactionalOperator::transactional)

A TransactionalOperator bean is configured in MongoConfig.java. The import path at ImportServiceCEImpl.java:552 already uses .as(transactionalOperator::transactional) for its multi-step writes - the snapshot path has no equivalent.

Failure scenario

  1. Developer creates a snapshot before a risky refactor.
  2. deleteAllByApplicationId commits - all previous snapshot chunks are gone.
  3. Server receives SIGTERM (deploy restart), OOM kill, or MongoDB connection drops mid-write.
  4. createSnapshots stops partway through - partial or zero chunks written.
  5. Snapshot feature reports success or fails with no clear error, but the application has lost its snapshot entirely.
  6. Developer encounters a problem with their refactor and tries to restore - finds no snapshot.

Fix

Inject TransactionalOperator into ApplicationSnapshotServiceCEImpl (it is already available in the application context) and wrap both operations:

java return applicationSnapshotRepository .deleteAllByApplicationId(branchedApplicationId) .thenMany(createSnapshots(branchedApplicationId, applicationJson)) .as(transactionalOperator::transactional);

Environment

Appsmith elease branch (2026-08-13), Java/Spring WebFlux, MongoDB.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions