tinyhumansai/openhuman · error
Failed to atomically replace config file: {e}
Error message
Failed to atomically replace config file: {e} What it means
`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.
Source
Thrown at src/openhuman/config/schema/load/impl_load.rs:741
fs::create_dir_all(parent_dir).await.with_context(|| {
format!(
"Failed to recreate config directory for atomic replace retry: {}",
parent_dir.display()
)
})?;
fs::rename(&temp_path, &self.config_path).await
}
result => result,
};
if let Err(e) = replace {
let _ = fs::remove_file(&temp_path).await;
if had_existing_config && backup_path.exists() {
fs::copy(&backup_path, &self.config_path)
.await
.context("Failed to restore config backup")?;
}
anyhow::bail!("Failed to atomically replace config file: {e}");
}
super::sync_directory(parent_dir).await?;
Ok(())
}
}
View on GitHub (pinned to 7491200858)
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.
Defensive patterns
Strategy: retry
Validate before calling
// Probe writability of the config dir before a settings save
let dir = config.config_path.parent().unwrap();
let probe = dir.join(format!(".probe-{}", uuid::Uuid::new_v4()));
tokio::fs::write(&probe, b"").await?;
let _ = tokio::fs::remove_file(&probe).await; Try / catch
match config.save().await {
Err(e) if e.to_string().contains("atomically replace config file") => {
// the save was rolled back — on-disk config is unchanged, safe to retry
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
config.save().await?
}
other => other?,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to atomically persist active workspace marker {}: {er
- Failed to atomically persist active user state {}: {error}
- Working directory '{}' is not a directory. Set a valid path
- Config path is a directory, not a file: {}
- OPENAI_CODEX_OAUTH_MISSING_AUTH_URL
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/e234169a4dd9d2d3.
Report an issue: GitHub.