tauri-apps / tauri-apps/plugins-workspace

[bug] `LazyStore` has chance of corrupting persisted file during power loss or system crash

Open
#3,085 0 comments 0 reactions 0 assignees View on GitHub
plugin: store type: bug
Dominant language
Rust
Stars
1.8k
Forks
602
Avg merge
4d 14h
Merged PRs (30d)
9

Description

**_Pre-face: I recognize this is very much an edge case, and that writes cannot be expected to always succeed during these circumstances. However as this issue did not seem to occur on the Tauri v1 version of this plugin, I figured it would be worth reporting._**

**Context**
A few months ago I migrated my application from Tauri v1 to v2, and because of that, updated its uses of the `Store` from the old v1 store plugin, to the `LazyStore` from the v2 plugin. Since the migration, I've started seeing a decent amount of reports of people losing their settings.

**The problem**
It seems that when the application does not terminate gracefully in a short period after calling `set` on the store (e.g. through power loss, system crash/bsod, or otherwise), the file used for the `LazyStore` has a chance to get corrupted.
I've seen the file keeping the same file size but being completely filled with nul/0 bytes ([example](https://github.com/user-attachments/files/23399616/corrupt_2.json)), to a completely empty file with no bytes in it ([example](https://github.com/user-attachments/files/23399627/corrupt_1.json)).

Many users who run my software run it for long periods of time, usually while running VR-related software, so system crashes while the software is running are not something completely out of the ordinary.

**Minimal Reproduction**
```ts
import { LazyStore } from "@tauri-apps/plugin-store";

// Store that auto saves with its default 100ms debounce
const store = new LazyStore("settings.dat");
// Some random data to save
const saveData = { bar: Array.from({ length: 1024 * 2 }, (_, i) => i) };

window.addEventListener("DOMContentLoaded", async () => {
const readData = await store.get("foo");
if (readData) {
console.log("Store data found.");
} else {
console.log("No store found (Or corrupted store file)"); // Happens if store file got corrupted, or did not yet exist
}
saveDataContinuously(); // Be careful, this will overwrite any corrupted data if you did not inspect the file yet.
});

function saveDataContinuously() {
console.log("Saving data continuously...");
setInterval(() => store.set("foo", saveData), 150); // 50ms above the default 100ms saving debounce value
}
```

1. Set up and run a fresh Tauri v2 application, Vanilla, TypeScript, with the store plugin, using the above code in `main.ts`.
2. Cut power to your PC, or trigger a BSOD.
3. After powering your PC back up, check the `settings.dat` file. You can possibly find it corrupted (either 0 bytes, or filled with nul bytes).

**Versions**
Tauri v2.9.2
Store plugin v2.4.1
Windows Version 10.0.26200 Build 26200

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.