{"record":{"id":"10a7538d138e83da","repo":"xai-org/grok-build","slug":"unmount-of-could-not-be-verified-still-mounted","errorCode":null,"errorMessage":"unmount of {} could not be verified (still mounted or mount table inconclusive); retaining backing and pin","messagePattern":"unmount of (.+?) could not be verified \\(still mounted or mount table inconclusive\\); retaining backing and pin","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/codegen/xai-fast-worktree/src/nfs/remove.rs","lineNumber":56,"sourceCode":"    if client.ping() {\n        match client.remove_worktree(worktree_path, false) {\n            Ok(()) => return report_after_daemon_unmount(worktree_path),\n            Err(e) => {\n                bail!(\"daemon RemoveWorktree failed: {e}\");\n            }\n        }\n    }\n    if dest_is_mountpoint(worktree_path) {\n        if lookup_from_markers(worktree_path).is_none() {\n            bail!(\n                \"{} is still a mountpoint without a grove marker; refusing umount/rm\",\n                worktree_path.display()\n            );\n        }\n        plain_umount(worktree_path)?;\n    }\n    if !super::dest_is_known_unmounted(worktree_path) {\n        bail!(\n            \"unmount of {} could not be verified (still mounted or mount table \\\n             inconclusive); retaining backing and pin\",\n            worktree_path.display()\n        );\n    }\n    let meta = lookup_nfs_meta(worktree_path);\n    if let Some(m) = meta.as_ref() {\n        let Some(id) = m.worktree_id.as_deref() else {\n            bail!(\n                \"unmounted dest {} has grove metadata without a worktree id; \\\n                 retaining pin and dest\",\n                worktree_path.display()\n            );\n        };\n        if !is_safe_worktree_id(id) {\n            bail!(\n                \"unmounted dest {} has unsafe worktree id {id:?}; retaining pin and dest\",\n                worktree_path.display()","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-fast-worktree/src/nfs/remove.rs#L38-L74","documentation":"After plain_umount, the code re-checks dest_is_known_unmounted to confirm the dest is really no longer mounted. If the unmount could not be verified (still listed in the mount table, or the table is unreadable), it refuses to proceed and keeps the backing directory and pin intact rather than deleting data beneath a possibly-live mount.","triggerScenarios":"plain_umount reported success (or was skipped) but the mount still appears in the mount table — lazy mounts, open file descriptors keeping it alive, submounts still attached — or dest_is_known_unmounted cannot confirm state.","commonSituations":"Processes (shells, editors, build daemons) holding cwd/fds inside the mount; umount returning EBUSY handled loosely; containers/sandboxes where /proc/mounts of the namespace isn't visible to the tool.","solutions":["Find and stop processes using the mount (lsof/fuser -v <path>), then retry removal","Use umount -l (lazy) or unmount submounts first, then re-verify the table","Run in the correct mount namespace (e.g. via nsenter) so the mount table is readable and accurate","Re-run try_nfs_remove once the table shows the dest unmounted"],"exampleFix":"// before\nCommand::new(\"umount\").arg(&path).status()?;\nremove_backing_and_pin(&path)?; // may delete under live mount\n// after\nCommand::new(\"fuser\").arg(\"-k\").arg(\"-m\").arg(&path).status()?;\nCommand::new(\"umount\").arg(&path).status()?;\nif dest_is_known_unmounted(&path) { remove_backing_and_pin(&path)?; }","handlingStrategy":"retry","validationCode":"fn unmounted(path: &Path) -> bool {\n    super::dest_is_known_unmounted(path)\n}\nif !unmounted(&path) {\n    let _ = Command::new(\"fuser\").arg(\"-k\").arg(\"-m\").arg(&path).status();\n    let _ = Command::new(\"umount\").arg(&path).status();\n}","typeGuard":null,"tryCatchPattern":"match try_nfs_remove(&path) {\n    Err(e) if e.to_string().contains(\"could not be verified\") => {\n        // kill holders, lazy-umount submounts, wait, then retry once\n    }\n    r => r?,\n}","preventionTips":["Ensure no process holds fds or cwd inside the mount","Unmount nested submounts before the dest","Run in the mount namespace where the mount exists so verification is accurate"],"tags":["umount","ebusy","safety-guard","mount"],"backgroundTag":"unmount-not-verified","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}