astrid-runtime/astrid · error

release archive is missing

Error message

release archive is missing '{name}': {error}

What it means

Every listed executable must physically exist in `extract_dir`. When `std::fs::symlink_metadata(extract_dir.join(name))` fails, `validate_replacement_inputs` re-raises the OS error wrapped as `release archive is missing '<name>'`. The set is rejected before any live files are touched, so the current installation stays intact.

Solutions

  1. Verify the file exists at `extract_dir.join(name)` and re-run extraction if it is missing
  2. Check the name's exact case and platform suffix against the extracted archive contents (list the dir and match)
  3. Use the same manifest/archive pair for extraction and the `names` list to avoid cross-release mismatches

Example fix

// before
replace_executable_set(&install_dir, &extract_dir, &["astrid"])?;
// after
let names: Vec<&str> = if cfg!(windows) { &["astrid.exe"] } else { &["astrid"] };
replace_executable_set(&install_dir, &extract_dir, names)?;
Defensive patterns

Strategy: validation

Validate before calling

let missing: Vec<_> = names.iter()
    .filter(|n| !extract_dir.join(n).exists())
    .collect();
if !missing.is_empty() {
    return Err(anyhow!("missing from extract dir: {missing:?}"));
}

Try / catch

match replace_executable_set(&install_dir, &extract_dir, names) {
    Err(e) if e.to_string().starts_with("release archive is missing") => {
        eprintln!("re-extract the archive; {e}");
    }
    other => other.map_err(Into::into),
}

Prevention

When it happens

Trigger: Calling `replace_executable_set` with a name absent from `extract_dir` — archive extraction skipped that file, the name was misquoted or case-mismatches (`Astrid` vs `astrid` on a case-sensitive filesystem), or the extracted platform suffix (e.g. `.exe`) was stripped from the name.

Common situations: Extracting a truncated or partially downloaded archive; wrong architecture/platform archive extracted while the name list came from a manifest for another platform; names built from a previous release's manifest that no longer match.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-core/src/platform_fs.rs:853

        ));
    }

    let mut unique = HashSet::with_capacity(names.len());
    for name in names {
        let mut components = Path::new(name).components();
        if !matches!(components.next(), Some(Component::Normal(_)))
            || components.next().is_some()
            || !unique.insert(*name)
        {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                format!("invalid or duplicate executable name '{name}'"),
            ));
        }

        let source = extract_dir.join(name);
        let metadata = std::fs::symlink_metadata(&source).map_err(|error| {
            io::Error::new(
                error.kind(),
                format!("release archive is missing '{name}': {error}"),
            )
        })?;
        if metadata.file_type().is_symlink() || !metadata.is_file() {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                format!("release executable is redirected or not regular: {name}"),
            ));
        }
    }
    Ok(())
}

#[cfg(not(windows))]
fn replace_executable_set_by_rename(
    install_dir: &Path,
    extract_dir: &Path,

View on GitHub (pinned to affd8760f4)