diff --git a/app/lib/entity/file/data_source.dart b/app/lib/entity/file/data_source.dart
index ad800240..a7e7c2be 100644
--- a/app/lib/entity/file/data_source.dart
+++ b/app/lib/entity/file/data_source.dart
@@ -568,6 +568,22 @@ class FileSqliteDbDataSource implements FileDataSource {
   static final _log = Logger("entity.file.data_source.FileSqliteDbDataSource");
 }
 
+class IntermediateSyncState {
+  const IntermediateSyncState({
+    required this.account,
+    required this.dir,
+    required this.remoteTouchEtag,
+    required this.files,
+    required this.shouldCache,
+  });
+
+  final Account account;
+  final File dir;
+  final String? remoteTouchEtag;
+  final List<File> files;
+  final bool shouldCache;
+}
+
 class FileCachedDataSource implements FileDataSource {
   FileCachedDataSource(
     this._c, {
@@ -598,21 +614,29 @@ class FileCachedDataSource implements FileDataSource {
     Account account,
     File dir, {
     required String? remoteTouchEtag,
+  }) async {
+    final state = await beginSync(
+      account,
+      dir,
+      remoteTouchEtag: remoteTouchEtag,
+    );
+    return concludeSync(state);
+  }
+
+  Future<IntermediateSyncState> beginSync(
+    Account account,
+    File dir, {
+    required String? remoteTouchEtag,
   }) async {
     try {
       final remote = await _remoteSrc.list(account, dir);
-      await FileSqliteCacheUpdater(_c)(account, dir, remote: remote);
-      if (shouldCheckCache) {
-        // update our local touch token to match the remote one
-        try {
-          _log.info("[list] Update outdated local etag: ${dir.path}");
-          await _c.touchManager.setLocalEtag(account, dir, remoteTouchEtag);
-        } catch (e, stacktrace) {
-          _log.shout("[list] Failed while setLocalToken", e, stacktrace);
-          // ignore error
-        }
-      }
-      return remote;
+      return IntermediateSyncState(
+        account: account,
+        dir: dir,
+        remoteTouchEtag: remoteTouchEtag,
+        files: remote,
+        shouldCache: true,
+      );
     } on ApiException catch (e) {
       if (e.response.statusCode == 404) {
         _log.info("[list] File removed: $dir");
@@ -622,7 +646,13 @@ class FileCachedDataSource implements FileDataSource {
           _log.warning(
               "[list] Failed while remove from db, file not cached?", e);
         }
-        return [];
+        return IntermediateSyncState(
+          account: account,
+          dir: dir,
+          remoteTouchEtag: remoteTouchEtag,
+          files: [],
+          shouldCache: false,
+        );
       } else if (e.response.statusCode == 403) {
         _log.info("[list] E2E encrypted dir: $dir");
         try {
@@ -633,13 +663,40 @@ class FileCachedDataSource implements FileDataSource {
           _log.warning(
               "[list] Failed while emptying from db, file not cached?", e);
         }
-        return [];
+        return IntermediateSyncState(
+          account: account,
+          dir: dir,
+          remoteTouchEtag: remoteTouchEtag,
+          files: [],
+          shouldCache: false,
+        );
       } else {
         rethrow;
       }
     }
   }
 
+  Future<List<File>> concludeSync(IntermediateSyncState state) async {
+    if (!state.shouldCache) {
+      return state.files;
+    }
+
+    await FileSqliteCacheUpdater(_c)(state.account, state.dir,
+        remote: state.files);
+    if (shouldCheckCache) {
+      // update our local touch token to match the remote one
+      try {
+        _log.info("[list] Update outdated local etag: ${state.dir.path}");
+        await _c.touchManager
+            .setLocalEtag(state.account, state.dir, state.remoteTouchEtag);
+      } catch (e, stacktrace) {
+        _log.shout("[list] Failed while setLocalToken", e, stacktrace);
+        // ignore error
+      }
+    }
+    return state.files;
+  }
+
   @override
   listSingle(Account account, File f) async {
     final remote = await _remoteSrc.listSingle(account, f);
diff --git a/app/lib/use_case/sync_dir.dart b/app/lib/use_case/sync_dir.dart
index 55ff7e48..d96b3fcd 100644
--- a/app/lib/use_case/sync_dir.dart
+++ b/app/lib/use_case/sync_dir.dart
@@ -56,9 +56,12 @@ class SyncDir {
     }
     _log.info("[_syncDir] Dir changed: ${remoteDir.path}");
 
-    final children = await FileCachedDataSource(_c, shouldCheckCache: true)
-        .sync(account, remoteDir, remoteTouchEtag: status.item2);
+    final dataSrc = FileCachedDataSource(_c, shouldCheckCache: true);
+    final syncState = await dataSrc.beginSync(account, remoteDir,
+        remoteTouchEtag: status.item2);
+    final children = syncState.files;
     if (!isRecursive) {
+      await dataSrc.concludeSync(syncState);
       return true;
     }
     final subDirs = children
@@ -88,6 +91,7 @@ class SyncDir {
       }
       progress.next();
     }
+    await dataSrc.concludeSync(syncState);
     return true;
   }