{"record":{"id":"e234169a4dd9d2d3","repo":"tinyhumansai/openhuman","slug":"failed-to-atomically-replace-config-file-e","errorCode":null,"errorMessage":"Failed to atomically replace config file: {e}","messagePattern":"Failed to atomically replace config file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/schema/load/impl_load.rs","lineNumber":741,"sourceCode":"                fs::create_dir_all(parent_dir).await.with_context(|| {\n                    format!(\n                        \"Failed to recreate config directory for atomic replace retry: {}\",\n                        parent_dir.display()\n                    )\n                })?;\n                fs::rename(&temp_path, &self.config_path).await\n            }\n            result => result,\n        };\n\n        if let Err(e) = replace {\n            let _ = fs::remove_file(&temp_path).await;\n            if had_existing_config && backup_path.exists() {\n                fs::copy(&backup_path, &self.config_path)\n                    .await\n                    .context(\"Failed to restore config backup\")?;\n            }\n            anyhow::bail!(\"Failed to atomically replace config file: {e}\");\n        }\n\n        super::sync_directory(parent_dir).await?;\n\n        Ok(())\n    }\n}\n","sourceCodeStart":723,"sourceCodeEnd":749,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/schema/load/impl_load.rs#L723-L749","documentation":"`Config::save` writes atomically: back up the existing file, write a temp file, `fs::rename` over the config path. If the final rename fails, the temp file is removed, the backup is copied back over the config path (surfacing `Failed to restore config backup` only if that also fails), and this bail reports the lost write. On-disk config is left at its pre-save state — the failure is a rollback, not corruption.","triggerScenarios":"Rename failures on the config directory: permission/ACL restrictions, config.toml held open by another process (Windows sharing violation, editor, antivirus, backup tool), a read-only or network-synced filesystem, or the temp file and target crossing a filesystem boundary.","commonSituations":"Windows machines with antivirus/backup tools touching config.toml during saves; configs on network drives or sync mounts (OneDrive/Dropbox) where renames fail; two core processes writing config concurrently.","solutions":["Retry the settings write — the failed attempt was rolled back, so state is consistent and the retry is safe.","Remove the lock holder: close other processes using config.toml, exclude the config dir from antivirus scanning, verify write permissions on the directory.","Move the workspace/config off read-only or aggressively-synced network storage if renames keep failing."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Probe writability of the config dir before a settings save\nlet dir = config.config_path.parent().unwrap();\nlet probe = dir.join(format!(\".probe-{}\", uuid::Uuid::new_v4()));\ntokio::fs::write(&probe, b\"\").await?;\nlet _ = tokio::fs::remove_file(&probe).await;","typeGuard":null,"tryCatchPattern":"match config.save().await {\n    Err(e) if e.to_string().contains(\"atomically replace config file\") => {\n        // the save was rolled back — on-disk config is unchanged, safe to retry\n        tokio::time::sleep(std::time::Duration::from_millis(500)).await;\n        config.save().await?\n    }\n    other => other?,\n}","preventionTips":["Close other processes holding config.toml open before settings writes","Keep the config dir off read-only or aggressively-synced network mounts","A failed save is rolled back — re-read the config before retrying so you retry against real state"],"tags":["config","save","atomic-write","filesystem","rollback"],"backgroundTag":"atomic-write-failed","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}