@@ -1441,10 +1441,13 @@ async function loadAccountsInternal(
14411441 }
14421442}
14431443
1444- async function loadAccountsForExport ( options ?: {
1445- persistMigrations ?: boolean ;
1446- } ) : Promise < AccountStorageV3 | null > {
1447- const persistMigrations = options ?. persistMigrations ?? true ;
1444+ async function loadAccountsForExport (
1445+ mode : "locked" | "unlocked" = "locked" ,
1446+ ) : Promise < AccountStorageV3 | null > {
1447+ // Export reuses this helper from both paths in `exportAccounts()`. Only the
1448+ // locked path may persist migrations; unlocked reads must remain side-effect
1449+ // free while another storage transaction holds the mutex for a different file.
1450+ const persistMigrations = mode === "locked" ;
14481451 const path = getStoragePath ( ) ;
14491452 const resetMarkerPath = getIntentionalResetMarkerPath ( path ) ;
14501453 const migratedLegacyStorage = await migrateLegacyProjectStorageIfNeeded (
@@ -1855,9 +1858,9 @@ export async function exportAccounts(
18551858 force,
18561859 currentStoragePath,
18571860 transactionState : getTransactionSnapshotState ( ) ,
1858- readCurrentStorageUnlocked : ( ) =>
1859- loadAccountsForExport ( { persistMigrations : false } ) ,
1860- readCurrentStorage : ( ) => withStorageLock ( ( ) => loadAccountsForExport ( ) ) ,
1861+ readCurrentStorageUnlocked : ( ) => loadAccountsForExport ( "unlocked" ) ,
1862+ readCurrentStorage : ( ) =>
1863+ withStorageLock ( ( ) => loadAccountsForExport ( "locked" ) ) ,
18611864 exportAccountsToFile,
18621865 beforeCommit,
18631866 logInfo : ( message , details ) => {
0 commit comments