{"record":{"id":"2505815015a6e88b","repo":"astrid-runtime/astrid","slug":"kernel-returned-an-unexpected-storage-unmount-resp-250581","errorCode":null,"errorMessage":"kernel returned an unexpected storage unmount response","messagePattern":"kernel returned an unexpected storage unmount response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/main.rs","lineNumber":332,"sourceCode":"        AdminResponseBody::Error(error) => {\n            bail!(\"kernel refused storage lifecycle request: {error}\")\n        },\n        _ => bail!(\"kernel returned an unexpected storage lifecycle response\"),\n    }\n}\n\nfn unmount_status(body: AdminResponseBody) -> Result<bool> {\n    match body {\n        AdminResponseBody::Success(_) => Ok(true),\n        AdminResponseBody::Error(error)\n            if error.contains(\"was not found\") || error.contains(\"expired or revoked\") =>\n        {\n            Ok(false)\n        },\n        AdminResponseBody::Error(error) => {\n            bail!(\"kernel refused storage unmount authorization: {error}\")\n        },\n        _ => bail!(\"kernel returned an unexpected storage unmount response\"),\n    }\n}\n\n#[cfg(windows)]\nfn prepare_mountpoint(\n    requested: Option<PathBuf>,\n    view: &astrid_core::storage_provider::StorageProviderViewV1,\n) -> Result<(PathBuf, bool)> {\n    let _ = view;\n    let mountpoint = requested.map_or_else(first_free_drive, Ok)?;\n    if !mountpoint.is_absolute() {\n        bail!(\"mountpoint must be absolute\");\n    }\n    if is_drive_target(&mountpoint) {\n        if std::fs::metadata(&mountpoint).is_ok() {\n            bail!(\n                \"Windows drive target is already in use: {}\",\n                mountpoint.display()","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/main.rs#L314-L350","documentation":"Thrown by `unmount_status` when the kernel's response to the unmount authorization check is neither `Success` nor a recognized `Error`. The provider cannot determine whether the lease is still valid, so it aborts the unmount rather than risking an inconsistent state.","triggerScenarios":"`unmount` performs the authorization check and the kernel returns an `AdminResponseBody` variant outside `Success`/`Error` — for instance a lease payload or an unrecognized enum variant from a newer kernel.","commonSituations":"Kernel and provider version mismatch after an admin API change; hitting the wrong admin endpoint that returns a lease or other typed payload instead of a status response.","solutions":["Match provider and kernel versions so response variants are understood","Check kernel logs for the actual response emitted to the unmount authorization request","Extend `unmount_status` to handle the newly introduced response variant"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_status_response(body: &AdminResponseBody) -> bool {\n    matches!(body, AdminResponseBody::Success(_) | AdminResponseBody::Error(_))\n}","tryCatchPattern":"match provider.unmount(lease).await {\n    Err(e) if e.to_string().contains(\"unexpected storage unmount response\") => {\n        // protocol mismatch: do not force-unmount; escalate to version fix\n    },\n    other => handle(other),\n}","preventionTips":["Align provider/kernel versions before rolling out unmount automation","Verify the unmount request targets the correct admin endpoint","Add tracing on kernel responses during unmount in staging"],"tags":["ipc","protocol-mismatch","unmount","winfsp"],"backgroundTag":"unexpected-api-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"}