BigPizzaV3/CodexPlusPlus · critical
failed to restore rollout file(s)
Error message
failed to restore {} rollout file(s): {} What it means
restore_bulk_session_rewrites iterates applied changes in reverse and calls restore_bulk_session_rewrite for each rollout file. Any per-file failure is collected with the file path; if any failures occurred, this aggregate error is raised listing how many files failed to restore and each `path: error`.
Solutions
- Inspect each `path: error` entry; resolve per-file causes (unlock, fix permissions) then retry the restore
- For files reported as changed before rollback, restore them from an external backup — the library refuses to overwrite files it did not rewrite
- Re-run the full provider sync to regenerate the affected rollout files from source data
- Check disk space and AV/indexer interference if many files failed at once
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check each planned path for writability
let bad: Vec<_> = plans.iter().filter(|p| metadata_writeable_failed(&p.path)).collect();
if !bad.is_empty() { return Err(format!("{} unwritable targets", bad.len())); } Try / catch
match restore_result {
Err(e) => {
let msg = e.to_string();
// msg enumerates "path: error" entries; parse and remediate per file
}
Ok(_) => {}
} Prevention
- Quiesce all writers of the rollout files before applying or rolling back
- Run under an account with write access to the rollout directories
- Monitor disk space; batch large rewrites into smaller groups
When it happens
Trigger: Calling the bulk-session-rewrite rollback path (directly or via the apply-failure handler) when one or more restore_bulk_session_rewrite calls return Err — e.g. hash checks fail or atomic_write_with cannot write the pre-image back.
Common situations: Rollout files modified between rewrite and rollback (hash mismatch); files locked by another process; disk or permission failures during the restore write; multiple files failing at once after a shared root cause.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- ; rollout rollback failed
- archived lookup task failed
- built-in Dream Skin theme cannot be deleted
- built-in Dream Skin theme is read-only
- cannot terminate Windows process id
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/8bf2c149108795ea.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-data/src/provider_sync.rs:3657
writer.write_all(line_ending.as_bytes())?;
rewritten = true;
}
if !rewritten {
writer.write_all(line.as_bytes())?;
}
}
Ok(format!("{:x}", hasher.finalize()))
}
fn restore_bulk_session_rewrites(changes: &[AppliedBulkSessionRewrite]) -> anyhow::Result<()> {
let mut restore_errors = Vec::new();
for change in changes.iter().rev() {
if let Err(error) = restore_bulk_session_rewrite(change) {
restore_errors.push(format!("{}: {error:#}", change.plan.path.display()));
}
}
if !restore_errors.is_empty() {
return Err(anyhow::anyhow!(
"failed to restore {} rollout file(s): {}",
restore_errors.len(),
restore_errors.join("; ")
));
}
Ok(())
}
fn restore_bulk_session_rewrite(change: &AppliedBulkSessionRewrite) -> anyhow::Result<()> {
if sha256_file(&change.plan.path)? != change.rewritten_sha256 {
return Err(anyhow::anyhow!(
"rollout changed before rollback: {}",
change.plan.path.display()
));
}
codex_plus_core::settings::atomic_write_with(&change.plan.path, |file| {
let mut writer = HashingWriter::new(BufWriter::new(file));View on GitHub (pinned to b1ed92e5e4)