{"record":{"id":"3e120b1064e22252","repo":"astrid-runtime/astrid","slug":"fuse-service-returned-an-incompatible-unmount-resp","errorCode":null,"errorMessage":"FUSE service returned an incompatible unmount response","messagePattern":"FUSE service returned an incompatible unmount response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/main.rs","lineNumber":878,"sourceCode":"        &record.mountpoint,\n        record.auto_created_mountpoint,\n    )?;\n    Ok(())\n}\n\nfn control_unmount(control_path: &Path, acting_principal: &astrid_core::PrincipalId) -> Result<()> {\n    match call_control(\n        control_path,\n        &ControlRequest::Unmount {\n            requested_by: acting_principal.clone(),\n        },\n    )? {\n        ControlResponse::Done => Ok(()),\n        ControlResponse::Failure { code, message } => {\n            bail!(\"FUSE service unmount failed [{code}]: {message}\")\n        },\n        ControlResponse::Status { .. } => {\n            bail!(\"FUSE service returned an incompatible unmount response\")\n        },\n    }\n}\n\nfn cleanup_mountpoint(mountpoint: &Path, auto_created: bool) -> Result<()> {\n    if auto_created\n        && !mountpoint::mountinfo_contains(mountpoint)?\n        && std::fs::symlink_metadata(mountpoint).is_ok_and(|metadata| metadata.is_dir())\n        && std::fs::read_dir(mountpoint)?.next().is_none()\n    {\n        let _ = std::fs::remove_dir(mountpoint);\n    }\n    Ok(())\n}\n\nfn lease_from_response(body: AdminResponseBody) -> Result<StorageMountLeaseV1> {\n    match body {\n        AdminResponseBody::StorageMountLease(lease) => Ok(*lease),","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/main.rs#L860-L896","documentation":"The unmount flow expects ControlResponse::Done (or a Failure) from the FUSE control service. Receiving a ControlResponse::Status instead means the service answered an unmount request with status information, which the client treats as incompatible and bails (crates/astrid-storage-provider-fuse/src/main.rs:878).","triggerScenarios":"Sending ControlRequest::Unmount and getting a Status response — indicating the peer is not the expected control service or the request was misinterpreted (protocol/version mismatch).","commonSituations":"A stale or foreign process listening on the control socket; client/service version skew where Unmount handling changed; racing reconnect to a service that just restarted.","solutions":["Verify the process bound to the control socket is the correct astrid FUSE service version and restart it if stale","Remove stale socket files and retry the unmount","Upgrade client and service together so ControlResponse variants line up"],"exampleFix":"// before\nsend_control(socket, ControlRequest::Unmount{..})?; // got Status back\n// after\nassert_control_service_version(socket)?; // confirm peer speaks same protocol\nsend_control(socket, ControlRequest::Unmount{..})?;","handlingStrategy":"type-guard","validationCode":"let ok = matches!(resp, ControlResponse::Done | ControlResponse::Failure { .. });","typeGuard":"fn is_unmount_response(resp: &ControlResponse) -> bool { matches!(resp, ControlResponse::Done | ControlResponse::Failure { .. }) }","tryCatchPattern":"match unmount(...) { Err(e) if e.to_string().contains(\"incompatible unmount response\") => { restart_service_and_retry()? }, r => r? }","preventionTips":["Verify the control socket peer before sending requests","Keep client/service protocol versions in sync","Restart stale services before lifecycle operations"],"tags":["fuse","unmount","protocol-mismatch","unexpected-response"],"backgroundTag":"unexpected-response-shape","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}