{"record":{"id":"0b32f2ae49d07284","repo":"Kuberwastaken/claurst","slug":"refusing-to-overwrite-malformed-settings-file","errorCode":null,"errorMessage":"Refusing to overwrite malformed settings file {}: {}","messagePattern":"Refusing to overwrite malformed settings file (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-rust/crates/core/src/lib.rs","lineNumber":1745,"sourceCode":"            } else {\n                Ok(Self::default())\n            }\n        }\n\n        fn load_from_path_sync(path: &Path) -> anyhow::Result<Self> {\n            if path.exists() {\n                let content = std::fs::read_to_string(path)?;\n                Self::parse_file(&content, path)\n            } else {\n                Ok(Self::default())\n            }\n        }\n\n        async fn save_to_path(&self, path: &Path) -> anyhow::Result<()> {\n            if path.exists() {\n                let content = tokio::fs::read_to_string(path).await?;\n                Self::parse_file(&content, path).map_err(|error| {\n                    anyhow::anyhow!(\n                        \"Refusing to overwrite malformed settings file {}: {}\",\n                        path.display(),\n                        error\n                    )\n                })?;\n            }\n            if let Some(parent) = path.parent() {\n                tokio::fs::create_dir_all(parent).await?;\n            }\n            let content = serde_json::to_string_pretty(self)?;\n            tokio::fs::write(path, content).await?;\n            Ok(())\n        }\n\n        fn save_to_path_sync(&self, path: &Path) -> anyhow::Result<()> {\n            if path.exists() {\n                let content = std::fs::read_to_string(path)?;\n                Self::parse_file(&content, path).map_err(|error| {","sourceCodeStart":1727,"sourceCodeEnd":1763,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/core/src/lib.rs#L1727-L1763","documentation":"The async settings save path (`save_to_path`) refuses to overwrite an existing settings file whose current contents do not parse as valid JSON. This is a safety guard: if the file is malformed (possibly due to a crash or user edit), rewriting it would silently destroy the user's configuration, so the save aborts instead.","triggerScenarios":"Calling any async settings-save API (e.g. persisting updated settings) where `path.exists()` and the on-disk content fails `Settings::parse_file` — i.e. the existing settings.json is invalid JSON or has the wrong shape for the settings struct.","commonSituations":"The user hand-edited settings.json and broke the syntax, then the app or a TUI command tries to persist a setting; a previous write was truncated mid-flight leaving corrupt JSON; an external tool replaced the file with non-JSON content.","solutions":["Fix or remove the malformed settings.json at the path shown (back it up first), then retry the save.","Validate the existing file with `jq . settings.json` to locate the syntax error and repair it before re-running the save.","If the file is unrecoverable, delete it so the next save starts from a fresh valid file."],"exampleFix":"cp settings.json settings.json.broken\njq . settings.json  # shows exact syntax error\necho '{}' > settings.json  # reset after backup if unrecoverable","handlingStrategy":"validation","validationCode":"// before calling an async save, ensure the current file parses:\nlet path = Settings::global_settings_path();\nif path.exists() {\n    let content = tokio::fs::read_to_string(&path).await?;\n    serde_json::from_str::<serde_json::Value>(&content)\n        .map_err(|e| anyhow::anyhow!(\"settings.json is malformed, repair before saving: {e}\"))?;\n}","typeGuard":"fn settings_file_parseable(content: &str) -> bool {\n    serde_json::from_str::<serde_json::Value>(content).is_ok()\n}","tryCatchPattern":"match settings.save().await {\n    Err(e) if e.to_string().contains(\"Refusing to overwrite malformed\") => {\n        eprintln!(\"{e:#}\"); eprintln!(\"Repair or delete settings.json, then retry.\");\n    }\n    other => other?,\n}","preventionTips":["Repair settings.json immediately after any parse error on load — don't keep running with a broken file.","Avoid writing settings.json with scripts that don't validate output; serialize through serde_json instead of string concatenation.","Check for crashed/interrupted writes (partial files) and delete truncated files.","Back up settings.json before bulk edits."],"tags":["json","config","file-write","data-loss-prevention"],"backgroundTag":"json-parse-error","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}