{"record":{"id":"8873ebd5f577373f","repo":"astrid-runtime/astrid","slug":"authenticated-macos-lifecycle-tool-is-redirected-o","errorCode":null,"errorMessage":"authenticated macOS lifecycle tool is redirected or not regular: {name}","messagePattern":"authenticated macOS lifecycle tool is redirected or not regular: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/self_update/mod.rs","lineNumber":412,"sourceCode":"    if !target.contains(\"-apple-darwin\") {\n        return Ok(());\n    }\n    let app = extract_dir.join(\"AstridFS.app\");\n    let app_metadata = std::fs::symlink_metadata(&app)\n        .with_context(|| format!(\"authenticated macOS release is missing {}\", app.display()))?;\n    anyhow::ensure!(\n        app_metadata.is_dir() && !app_metadata.file_type().is_symlink(),\n        \"authenticated AstridFS.app is redirected or not a directory\"\n    );\n    for name in [\"manage-macos-fskit.sh\", \"validate-macos-fskit.sh\"] {\n        let source = extract_dir.join(\"macos\").join(name);\n        let metadata = std::fs::symlink_metadata(&source).with_context(|| {\n            format!(\n                \"authenticated macOS release is missing {}\",\n                source.display()\n            )\n        })?;\n        anyhow::ensure!(\n            metadata.is_file() && !metadata.file_type().is_symlink(),\n            \"authenticated macOS lifecycle tool is redirected or not regular: {name}\"\n        );\n        std::fs::copy(&source, extract_dir.join(name))?;\n    }\n    Ok(())\n}\nfn restore_managed_set(\n    install_dir: &Path,\n    names: &[&str],\n    previously_present: &[bool],\n) -> anyhow::Result<()> {\n    let rollback = tempfile::tempdir_in(install_dir)?;\n    let mut staged = Vec::new();\n    for (name, present) in names.iter().zip(previously_present) {\n        if *present {\n            let temporary = rollback.path().join(name);\n            std::fs::copy(install_dir.join(format!(\"{name}.bak\")), &temporary)?;","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/self_update/mod.rs#L394-L430","documentation":"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.","triggerScenarios":"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.","commonSituations":"Tampered or third-party repackaged release archives; packaging pipelines that replaced scripts with symlinks; extraction tooling that rewrote entries as links.","solutions":["Re-download the official signed release and retry the update","List archive contents (tar -tvf) and verify macos/*.sh are regular files","Fix the release packaging to emit real regular-file scripts","Clear the partially-extracted directory and re-run the update"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn is_regular_file(p: &Path) -> bool {\n    std::fs::symlink_metadata(p).map(|m| m.is_file() && !m.file_type().is_symlink()).unwrap_or(false)\n}\nfor name in [\"manage-macos-fskit.sh\", \"validate-macos-fskit.sh\"] {\n    assert!(is_regular_file(&extract_dir.join(\"macos\").join(name)), \"{name} must be a regular file\");\n}","typeGuard":"fn is_regular_file(p: &Path) -> bool {\n    std::fs::symlink_metadata(p)\n        .map(|m| m.is_file() && !m.file_type().is_symlink())\n        .unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Verify macos/*.sh entries are regular files in every release build","Refuse to run lifecycle scripts via symlinked paths","Only extract archives from the authenticated channel","Clean stale extractions before retrying an update"],"tags":["macos","security","symlink","archive"],"backgroundTag":"path-traversal-blocked","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}