{"record":{"id":"5045ef10ba51a35f","repo":"rustdesk/rustdesk","slug":"root-update-required-installed-plist-is-missing","errorCode":null,"errorMessage":"[root-update] required installed plist is missing: {}","messagePattern":"\\[root-update\\] required installed plist is missing: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/platform/macos.rs","lineNumber":1033,"sourceCode":"}\n\npub fn update_to(_file: &str) -> ResultType<()> {\n    let update_temp_dir = get_update_temp_dir_string();\n    update_extracted(&update_temp_dir)?;\n    Ok(())\n}\n\nfn backup_update_plist(source: &str, backup: &str) -> ResultType<()> {\n    match std::fs::symlink_metadata(source) {\n        Ok(metadata) => {\n            if !metadata.file_type().is_file() {\n                bail!(\"[root-update] plist is not a regular file: {}\", source);\n            }\n            std::fs::copy(source, backup)?;\n            Ok(())\n        }\n        Err(err) if err.kind() == std::io::ErrorKind::NotFound => {\n            bail!(\"[root-update] required installed plist is missing: {}\", source)\n        }\n        Err(err) => Err(err.into()),\n    }\n}\n\nfn validate_update_tree(path: &Path, framework_root: Option<&Path>) -> ResultType<()> {\n    let metadata = std::fs::symlink_metadata(path)?;\n    if metadata.file_type().is_symlink() {\n        // Frameworks legitimately use internal symlinks (Resources,\n        // Versions/Current), but never allow a link to leave its framework.\n        let Some(framework_root) = framework_root else {\n            bail!(\"[root-update] symlink outside framework: {}\", path.display());\n        };\n        let target = std::fs::read_link(path)?;\n        let target = if target.is_absolute() {\n            target\n        } else {\n            path.parent().unwrap_or(Path::new(\"/\")).join(target)","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540/src/platform/macos.rs#L1015-L1051","documentation":"The root-update flow requires the already-installed launchd plist to exist so it can be backed up and rewritten. `backup_update_plist` checks `symlink_metadata` and explicitly converts an `ErrorKind::NotFound` result into this bail, aborting the update rather than proceeding without a valid installed service definition.","triggerScenarios":"Running the privileged update (src/platform/macos.rs:1033) when the expected installed plist — such as /Library/LaunchAgents/{agent} or the root daemon plist referenced by the update routine — does not exist because RustDesk was never installed as a service or the plist was deleted.","commonSituations":"User downloaded a new build and ran --update without ever running the install step; manual cleanup (`launchctl unload` + rm) removed the plist; an OS reinstall or cleanup utility wiped /Library/LaunchAgents; plist name changed between RustDesk versions.","solutions":["Install the service first: run `sudo /Applications/RustDesk.app/Contents/MacOS/RustDesk --install` so the plist is created, then update.","Verify the expected plist exists: `ls /Library/LaunchAgents | grep -i rustdesk` (and /Library/LaunchDaemons).","If upgrading from an old version, check for a renamed plist and install the new one instead of updating in place.","Reinstall the app bundle entirely if the installation state is unclear."],"exampleFix":"// before\nsudo RustDesk --update   # fails: plist never installed\n// after\nsudo RustDesk --install --silent\nsudo RustDesk --update","handlingStrategy":"try-catch","validationCode":"let agent = format!(\"{}_server.plist\", full_name);\nlet path = format!(\"/Library/LaunchAgents/{}\", agent);\nif !std::path::Path::new(&path).exists() {\n    eprintln!(\"Service not installed; run --install first\");\n}","typeGuard":"fn plist_installed(full_name: &str) -> bool {\n    std::path::Path::new(&format!(\"/Library/LaunchAgents/{}_server.plist\", full_name)).exists()\n}","tryCatchPattern":"match update_root() {\n    Err(e) if e.to_string().contains(\"required installed plist is missing\") => {\n        eprintln!(\"RustDesk service not installed — running install first\");\n        install_service()?;\n        update_root()?;\n    }\n    other => other,\n}","preventionTips":["Always install the service (--install) before attempting an in-place update.","Check /Library/LaunchAgents and /Library/LaunchDaemons for the plist before updating.","Avoid cleanup tools that purge /Library/Launch* without reinstalling services.","When migrating versions, verify whether the plist naming changed and install fresh instead of updating."],"tags":["macos","plist","file-not-found","update","launchd"],"backgroundTag":"file-not-found","analyzedSha":"91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540","analyzedAt":"2026-09-10T19:53:44.083Z","contentChangedAt":"2026-09-10T19:53:44.083Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}