astrid-runtime/astrid · error

authenticated macOS lifecycle tool is redirected or not regu

Error message

authenticated macOS lifecycle tool is redirected or not regular: {name}

What it means

prepare_macos_update_assets copies the macOS FSKit lifecycle scripts (manage-macos-fskit.sh, validate-macos-fskit.sh) out of the verified update archive. Before copying, each must be a regular file and not a symlink. This error fires when one of these lifecycle tools is missing its expected form, blocking a potentially redirected file from being executed later with elevated privileges.

Source

Thrown at crates/astrid-cli/src/commands/self_update/mod.rs:412

    if !target.contains("-apple-darwin") {
        return Ok(());
    }
    let app = extract_dir.join("AstridFS.app");
    let app_metadata = std::fs::symlink_metadata(&app)
        .with_context(|| format!("authenticated macOS release is missing {}", app.display()))?;
    anyhow::ensure!(
        app_metadata.is_dir() && !app_metadata.file_type().is_symlink(),
        "authenticated AstridFS.app is redirected or not a directory"
    );
    for name in ["manage-macos-fskit.sh", "validate-macos-fskit.sh"] {
        let source = extract_dir.join("macos").join(name);
        let metadata = std::fs::symlink_metadata(&source).with_context(|| {
            format!(
                "authenticated macOS release is missing {}",
                source.display()
            )
        })?;
        anyhow::ensure!(
            metadata.is_file() && !metadata.file_type().is_symlink(),
            "authenticated macOS lifecycle tool is redirected or not regular: {name}"
        );
        std::fs::copy(&source, extract_dir.join(name))?;
    }
    Ok(())
}
fn restore_managed_set(
    install_dir: &Path,
    names: &[&str],
    previously_present: &[bool],
) -> anyhow::Result<()> {
    let rollback = tempfile::tempdir_in(install_dir)?;
    let mut staged = Vec::new();
    for (name, present) in names.iter().zip(previously_present) {
        if *present {
            let temporary = rollback.path().join(name);
            std::fs::copy(install_dir.join(format!("{name}.bak")), &temporary)?;

View on GitHub (pinned to affd8760f4)

Solutions

  1. Re-download the official signed release and retry the update
  2. List archive contents (tar -tvf) and verify macos/*.sh are regular files
  3. Fix the release packaging to emit real regular-file scripts
  4. Clear the partially-extracted directory and re-run the update
Defensive patterns

Strategy: validation

Validate before calling

fn is_regular_file(p: &Path) -> bool {
    std::fs::symlink_metadata(p).map(|m| m.is_file() && !m.file_type().is_symlink()).unwrap_or(false)
}
for name in ["manage-macos-fskit.sh", "validate-macos-fskit.sh"] {
    assert!(is_regular_file(&extract_dir.join("macos").join(name)), "{name} must be a regular file");
}

Type guard

fn is_regular_file(p: &Path) -> bool {
    std::fs::symlink_metadata(p)
        .map(|m| m.is_file() && !m.file_type().is_symlink())
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: apply_authenticated_update handling a -apple-darwin archive where extract_dir/macos/manage-macos-fskit.sh or validate-macos-fskit.sh is a symlink, a directory, or otherwise not a regular file per symlink_metadata.

Common situations: Tampered or third-party repackaged release archives; packaging pipelines that replaced scripts with symlinks; extraction tooling that rewrote entries as links.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


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