tinyhumansai/openhuman · error

{err}; rollback from {} to {} also failed: {restore_err}

Error message

{err}; rollback from {} to {} also failed: {restore_err}

What it means

Wraps a doubly-failed atomic-install: fs::rename of the staged Python distribution onto final_dest failed (context: 'renaming staged X -> Y'), and the best-effort rollback — renaming the backed-up previous installation back to final_dest — failed too. The error text chains the original cause and the restore failure. This leaves the user's Python install directory in a broken state (previous runtime moved aside, new one not installed), so it is escalated instead of swallowed. Typical causes: cross-filesystem rename, files locked by a running process (Windows), or permission problems.

Source

Thrown at src/openhuman/runtime/python/extractor.rs:95

                    final_dest.display(),
                    candidate.display()
                )
            })?;
            Some(candidate)
        } else {
            None
        };

        if let Err(err) = fs::rename(&staged, &final_dest).with_context(|| {
            format!(
                "renaming staged {} -> {}",
                staged.display(),
                final_dest.display()
            )
        }) {
            if let Some(backup_path) = backup.as_ref() {
                if let Err(restore_err) = fs::rename(backup_path, &final_dest) {
                    return Err(anyhow!(
                        "{err}; rollback from {} to {} also failed: {restore_err}",
                        backup_path.display(),
                        final_dest.display()
                    ));
                }
            }
            return Err(err);
        }

        if let Some(backup_path) = backup {
            let _ = fs::remove_dir_all(backup_path);
        }

        Ok(final_dest)
    })
    .await
    .context("spawn_blocking join failure during atomic install")?
}

View on GitHub (pinned to 7491200858)

Solutions

  1. Manually inspect final_dest and the backup path; restore or delete whichever is left in place.
  2. Ensure no process is holding files under the destination open (running REPLs, spawned children) and retry the install.
  3. Ensure staged dir and destination are on the same filesystem, or switch to copy+delete instead of rename.
  4. Re-run the installation after fixing permissions on the runtime directory.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/openhuman/runtime/python/extractor.rs:95 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/a43df99b77b88007. Report an issue: GitHub.