tinyhumansai/openhuman · error

expected one top-level folder under {}, found {n}

Error message

expected one top-level folder under {}, found {n}

What it means

The counterpart guard in find_single_top_level(): after listing and sorting the extract root, more than one top-level directory was found (n != 1), so the extractor cannot decide which folder is the Python installation to move into place. Fires on malformed or unexpected archives (nested layouts, junk directories bundled into the tarball) or a stale, non-empty extract root left by a previous failed run. Generic guard; faulty input is the set of extracted top-level entries.

Source

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

    let mut entries = fs::read_dir(extract_root)
        .with_context(|| format!("listing {}", extract_root.display()))?
        .collect::<Result<Vec<_>, _>>()
        .with_context(|| format!("reading entries of {}", extract_root.display()))?;
    entries.sort_by_key(|e| e.file_name());

    let mut dirs = entries
        .into_iter()
        .filter(|e| e.file_type().map(|t| t.is_dir()).unwrap_or(false))
        .map(|e| e.path())
        .collect::<Vec<_>>();

    match dirs.len() {
        1 => Ok(dirs.pop().expect("single dir")),
        0 => Err(anyhow!(
            "expected one top-level folder under {}, found none",
            extract_root.display()
        )),
        n => Err(anyhow!(
            "expected one top-level folder under {}, found {n}",
            extract_root.display()
        )),
    }
}

pub async fn atomic_install(staged: &Path, final_dest: &Path) -> Result<PathBuf> {
    let staged = staged.to_path_buf();
    let final_dest = final_dest.to_path_buf();

    tokio::task::spawn_blocking(move || -> Result<PathBuf> {
        if let Some(parent) = final_dest.parent() {
            fs::create_dir_all(parent)
                .with_context(|| format!("creating parent {}", parent.display()))?;
        }

        let backup = if final_dest.exists() {
            let candidate = final_dest.with_extension(format!("old-{}", std::process::id()));

View on GitHub (pinned to 7491200858)

Solutions

  1. Clear the extract root of leftover content from prior installs and retry the download+extract.
  2. Prefer/validate the single expected cpython-* directory name if upstream ever ships extra top-level entries.
  3. Verify the downloaded asset is the install_only variant, whose layout is exactly one top-level folder.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/openhuman/runtime/python/extractor.rs:55 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/4e57946c806e2a83. Report an issue: GitHub.