{"record":{"id":"f8b30ff43ba519b2","repo":"astrid-runtime/astrid","slug":"launch-error-failed-to-fully-roll-back-unregi","errorCode":null,"errorMessage":"{launch_error:#}; failed to fully roll back unregistered FUSE mount: {rollback_error:#}","messagePattern":"(.+?); failed to fully roll back unregistered FUSE mount: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/rollback.rs","lineNumber":11,"sourceCode":"//! Fail-closed completion for mounts that never reached the durable registry.\n\nuse anyhow::{Result, bail};\n\npub(crate) fn preserve_launch_error(\n    launch_error: anyhow::Error,\n    rollback: Result<()>,\n) -> anyhow::Error {\n    match rollback {\n        Ok(()) => launch_error,\n        Err(rollback_error) => anyhow::anyhow!(\n            \"{launch_error:#}; failed to fully roll back unregistered FUSE mount: {rollback_error:#}\"\n        ),\n    }\n}\n\npub(crate) fn finish_cleanup(\n    mut failures: Vec<String>,\n    detach: Result<()>,\n    cleanup: impl FnOnce() -> Result<()>,\n) -> Result<()> {\n    match detach {\n        Ok(()) => {\n            if let Err(error) = cleanup() {\n                failures.push(format!(\"remove service artifacts: {error:#}\"));\n            }\n        },\n        Err(error) => failures.push(format!(\"detach mountpoint: {error:#}\")),\n    }","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/rollback.rs#L1-L29","documentation":"preserve_launch_error combines a FUSE mount launch failure with a subsequent rollback failure. If the launch failed AND unregistering/cleanup also failed, both errors are chained into one message so neither is lost.","triggerScenarios":"A FUSE mount launch fails (bad lease, spawn error), then the rollback path (unregister from registry, kill daemon, lazy unmount) also errors — e.g. the registry lock cannot be taken or the mountpoint cannot be unmounted.","commonSituations":"Partial-failure during a crashed prior run: registry record already gone plus mountpoint busy; concurrent operations mutating the registry while rollback runs; unmount needing root while launch failed for an unrelated reason.","solutions":["Read the first segment ({launch_error:#}) for the root cause of the failed mount","Read the second segment ({rollback_error:#}) to clean up leftover state manually (registry record, mountpoint)","Manually unregister the mount record and lazy-unmount the leftover mountpoint","Retry the whole operation once state is clean"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-validate lease before launch to avoid launch+rollback double failure\nvalidate_lease(&lease)?; // checks mount_id, mountpoint, provider fields","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"failed to fully roll back\") => {\n        // e contains both launch and rollback causes; clean both manually\n        manual_unregister(&mount_id);\n        let _ = lazy_unmount(&mountpoint);\n    }\n    r => r,\n}","preventionTips":["Read both chained segments of the message to fix root cause and leftover state","Clean registry + mountpoint before retrying after a partial failure","Avoid concurrent lifecycle operations on the same mount_id","Validate leases before spawning the daemon"],"tags":["fuse","rollback","cleanup","error-chaining"],"backgroundTag":"invalid-state-transition","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"}