{"record":{"id":"4c9622d4ea4f26b7","repo":"block/buzz","slug":"error-and-the-local-stores-could-not-be-restore","errorCode":null,"errorMessage":"{error} (and the local stores could not be restored: {restore_errors})","messagePattern":"(.+?) \\(and the local stores could not be restored: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"desktop/src-tauri/src/managed_agents/storage.rs","lineNumber":708,"sourceCode":"///\n/// Both restores are attempted independently, so a restore failure in one\n/// store does not prevent the other; errors from both are aggregated (I5).\npub(crate) fn commit_stores_with_snapshots(\n    personas_path: &Path,\n    teams_path: &Path,\n    personas_snap: StoreSnapshot,\n    teams_snap: StoreSnapshot,\n    write_personas: impl FnOnce() -> Result<(), String>,\n    write_teams: impl FnOnce() -> Result<(), String>,\n) -> Result<(), String> {\n    if let Err(error) = write_personas().and_then(|()| write_teams()) {\n        let personas_err = restore_store(personas_path, personas_snap).err();\n        let teams_err = restore_store(teams_path, teams_snap).err();\n        let restore_errors: Vec<&str> = [personas_err.as_deref(), teams_err.as_deref()]\n            .into_iter()\n            .flatten()\n            .collect();\n        if !restore_errors.is_empty() {\n            return Err(format!(\n                \"{error} (and the local stores could not be restored: {})\",\n                restore_errors.join(\"; \")\n            ));\n        }\n        return Err(error);\n    }\n    Ok(())\n}\n\n/// Maximum log file size before rotation (10 MB).\nconst MAX_LOG_FILE_SIZE: u64 = 10 * 1024 * 1024;\n\n/// If `path` exceeds [`MAX_LOG_FILE_SIZE`], rotate it to `<path>.1`.\nfn maybe_rotate_log(path: &Path) {\n    let size = match fs::metadata(path) {\n        Ok(m) => m.len(),\n        Err(_) => return,","sourceCodeStart":690,"sourceCodeEnd":726,"githubUrl":"https://github.com/block/buzz/blob/eed74bde2f4797714335ac10c56c0b0244c1def4/desktop/src-tauri/src/managed_agents/storage.rs#L690-L726","documentation":"Error string built in `commit_stores_with_snapshots` (desktop managed-agents storage): when committing the personas/teams stores fails, the code attempts to restore both stores from in-memory snapshots; if those restores also fail, it returns the original error annotated with every restore failure: `\"{error} (and the local stores could not be restored: {restore_errors})\"`. It signals double failure — the commit failed AND the rollback failed, leaving local state potentially inconsistent.","triggerScenarios":"Writing personas_path or teams_path fails (disk full, permission denied, file locked by the running app) during commit, then restore_store also fails on the same paths for the same reasons while rolling back from the snapshots.","commonSituations":"macOS/Windows file locks while the desktop app or an agent process holds the JSON store open, full disk, antivirus blocking writes, or path permission changes after an OS update.","solutions":["Close other app instances/processes holding the managed-agent store files, then retry the operation.","Check disk space and write permissions on the store directory (e.g. ~/Library/Application Support/<app>/managed_agents).","Back up the personas/teams store files manually, then delete or repair the corrupt ones so the app can recreate them.","In code, perform restores to temp files plus atomic rename, and retry the restore with backoff before declaring the stores unrestorable."],"exampleFix":"// before\nreturn Err(format!(\n    \"{error} (and the local stores could not be restored: {})\",\n    restore_errors.join(\"; \")\n));\n// after\ntracing::error!(restore_errors = ?restore_errors, \"managed-agent commit failed and restore failed\");\nErr(anyhow!(\n    \"{error} (and the local stores could not be restored: {}; inspect the store directory and back up files before retrying)\",\n    restore_errors.join(\"; \")\n))","handlingStrategy":"fallback","validationCode":"// check writability of both store paths before committing\nfor path in [personas_path, teams_path] {\n    let probe = path.with_extension(\".probe\");\n    std::fs::write(&probe, b\"ok\").map_err(|e| format!(\"store dir not writable ({}): {e}\", path.display()))?;\n    let _ = std::fs::remove_file(&probe);\n}","typeGuard":null,"tryCatchPattern":"if let Err(commit_err) = commit_stores_with_snapshots(...).await {\n    match restore_stores().await {\n        Ok(()) => warn!(\"commit failed but stores restored: {commit_err}\"),\n        Err(restore_err) => error!(\"commit failed AND restore failed: {commit_err}; restore: {restore_err} — back up the store directory before retrying\"),\n    }\n}","preventionTips":["Write stores to temp files and atomically rename so partial commits never happen.","Snapshot before commit and verify snapshot files are readable before mutating originals.","Monitor disk space in the app's data directory.","Take an app-level backup of personas/teams stores before risky updates."],"tags":["rust","desktop","tauri","file-io","state-corruption"],"backgroundTag":"store-commit-rollback-failed","analyzedSha":"eed74bde2f4797714335ac10c56c0b0244c1def4","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}