{"record":{"id":"380f0bfbec3c21ec","repo":"astrid-runtime/astrid","slug":"mountpoint-is-already-mounted","errorCode":null,"errorMessage":"mountpoint is already mounted: {}","messagePattern":"mountpoint is already mounted: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/main.rs","lineNumber":820,"sourceCode":"        .to_owned();\n    let registry: BTreeMap<String, registry::MountRecord> = registry::load_registry()?;\n    let Some(record) = registry.get(&key).cloned() else {\n        return Ok(());\n    };\n    let status = kernel_lease_status(client, &record.mount_id).await?;\n    let Some(status) = status else {\n        cleanup_stale_record(client, acting_principal, &record).await?;\n        return Ok(());\n    };\n    validate_record(&record, &status)?;\n    match call_control(\n        &record.control_path,\n        &ControlRequest::Status {\n            requested_by: record.requested_by.clone(),\n        },\n    ) {\n        Ok(ControlResponse::Status { access }) if access == status.access => {\n            bail!(\"mountpoint is already mounted: {}\", mountpoint.display())\n        },\n        Ok(ControlResponse::Status { access }) => {\n            bail!(\"registered FUSE service access {access:?} does not match its lease\")\n        },\n        Ok(_) => bail!(\"registered FUSE service returned an incompatible status response\"),\n        Err(_) => {\n            cleanup_stale_record(client, acting_principal, &record).await?;\n            Ok(())\n        },\n    }\n}\n\nasync fn cleanup_stale_record(\n    client: &mut AdminClient,\n    acting_principal: &astrid_core::PrincipalId,\n    record: &registry::MountRecord,\n) -> Result<()> {\n    let lease_is_live = kernel_lease_status(client, &record.mount_id)","sourceCodeStart":802,"sourceCodeEnd":838,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/main.rs#L802-L838","documentation":"ensure_mountpoint_available finds a registry record for the mountpoint, confirms the kernel lease is live and metadata matches, then probes the running FUSE service via a Status control request. If the service answers with matching access, the mountpoint is genuinely mounted and serving — remounting would fail — so the provider bails telling the user the mountpoint is already mounted.","triggerScenarios":"Calling the mount operation for a mountpoint that already has a live lease and a healthy FUSE service answering ControlRequest::Status with access equal to the lease's access. Happens on duplicate mount commands, re-running a script, or two processes mounting the same path concurrently.","commonSituations":"CI or shell scripts that run 'mount' without checking current state; a teammate's/dev's earlier mount still active; automation retrying after a timeout though the first attempt actually succeeded.","solutions":["Treat it as success if the mount already matches your intent: check status first and skip mounting if active","Unmount the existing mount first (provider unmount command or fusermount -u) then remount if a fresh mount is required","Serialize mount operations (locks/script guards) so concurrent runs don't race on the same mountpoint","If the existing mount is unwanted/stale, unmount it with the requesting principal so the registry record is cleaned"],"exampleFix":"// before: blind remount\nmount(client, &principal, mountpoint).await?;\n// after: idempotent check\nif control_status_says_mounted(mountpoint) {\n    eprintln!(\"{} already mounted, skipping\", mountpoint.display());\n} else {\n    mount(client, &principal, mountpoint).await?;\n}","handlingStrategy":"validation","validationCode":"// Probe before mounting: is the mountpoint already served?\nif let Ok(Some(record)) = registry::record_for_mountpoint(mountpoint) {\n    if let Ok(ControlResponse::Status { .. }) = call_control(&record.control_path, &ControlRequest::Status { requested_by: record.requested_by.clone() }) {\n        eprintln!(\"{} already mounted; skipping\", mountpoint.display());\n        return Ok(());\n    }\n}","typeGuard":"fn mountpoint_in_use(mountpoint: &Path) -> bool {\n    // /proc/mounts or findmnt check for an active FUSE mount at this path\n    std::fs::read_to_string(\"/proc/mounts\")\n        .map(|m| m.lines().any(|l| l.split_whitespace().nth(1) == Some(&mountpoint.to_string_lossy())))\n        .unwrap_or(false)\n}","tryCatchPattern":"match mount(client, &principal, mountpoint).await {\n    Err(e) if e.to_string().contains(\"mountpoint is already mounted\") => {\n        // idempotent success: the mount already exists with the same access\n        Ok(())\n    }\n    other => other,\n}","preventionTips":["Make mount flows idempotent: check status (control socket or /proc/mounts) before mounting","Serialize mount operations with a lock so concurrent scripts/CI jobs don't race","On retry-after-timeout, first verify whether the original mount actually succeeded","Unmount explicitly before remounting when a fresh mount is genuinely required"],"tags":["fuse","mount","idempotency","storage"],"backgroundTag":"file-already-exists","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"}