astrid-runtime/astrid · error

durable capsule archive path is not UTF-8

Error message

durable capsule archive path is not UTF-8

What it means

read_archive_files enumerates every entry in a durable capsule archive and requires each member path to be valid UTF-8 so names can be normalized ('\' -> '/') and checked for duplicates across files and directories. An entry whose path is not valid UTF-8 aborts the whole read with this error.

Solutions

  1. Inspect archive entry names to locate the non-UTF-8 path and rename it before republishing.
  2. Rebuild the durable package with a UTF-8 locale so tar records UTF-8 names.
  3. Run convmv on the source tree to convert filenames to UTF-8, then republish the capsule.
  4. Verify the published capsule with the verification path (read_verified_durable_package) after republishing.

Example fix

// before
convmv --notest -r ./src  # skipping conversion leaves non-UTF-8 names
// after
convmv -f latin1 -t utf8 -r --notest ./src && capsule publish ./src
Defensive patterns

Strategy: validation

Validate before calling

fn durable_paths_utf8(tar_path: &std::path::Path) -> anyhow::Result<()> {
    let f = std::fs::File::open(tar_path)?;
    let mut tar = tar::Archive::new(std::io::BufReader::new(f));
    for entry in tar.entries()? {
        let p = entry?.path()?.to_path_buf();
        if p.to_str().is_none() {
            anyhow::bail!("durable archive has non-UTF-8 path: {}", p.display());
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: read_verified_durable_package_for_owner (and the cross-binding mismatch test path) processes a durable archive containing an entry with raw non-UTF-8 path bytes — typically archives produced on non-UTF-8 filesystems or by legacy packing tools.

Common situations: Durable packages built on hosts with legacy locale settings; archives extracted from external sources and republished without path sanitization; Windows-created archives with codepage-encoded names.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/6709b318e964f897. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-capsule-install/src/storage.rs:382

        if path.is_absolute()
            || path.components().any(|component| {
                matches!(
                    component,
                    std::path::Component::ParentDir | std::path::Component::RootDir
                )
            })
        {
            bail!("durable capsule archive contains unsafe path");
        }

        let entry_type = entry.header().entry_type();
        if !entry_type.is_dir() && !entry_type.is_file() {
            bail!("durable capsule archive contains a link or special file");
        }

        let name = path
            .to_str()
            .ok_or_else(|| anyhow::anyhow!("durable capsule archive path is not UTF-8"))?
            .replace('\\', "/");
        if files.contains_key(&name) || directories.contains(&name) {
            bail!("durable capsule archive contains duplicate path {name}");
        }
        if entry_type.is_dir() {
            if !directories.insert(name) {
                bail!("durable capsule archive contains duplicate directory path");
            }
            continue;
        }

        let mut bytes = Vec::new();
        entry
            .read_to_end(&mut bytes)
            .with_context(|| format!("read durable capsule archive file {name}"))?;
        files.insert(name, bytes);
    }
    Ok(ArchiveInventory { files, directories })

View on GitHub (pinned to affd8760f4)