{"record":{"id":"3f6f17795623a05b","repo":"wasmerio/wasmer","slug":"journal-restore-error-failed-to-remove-directory","errorCode":null,"errorMessage":"journal restore error: failed to remove directory - {err}","messagePattern":"journal restore error: failed to remove directory - (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/wasix/src/journal/effector/syscalls/path_remove_directory.rs","lineNumber":41,"sourceCode":"\n    pub fn apply_path_remove_directory(\n        ctx: &mut FunctionEnvMut<'_, WasiEnv>,\n        fd: Fd,\n        path: &str,\n    ) -> anyhow::Result<()> {\n        // see `VIRTUAL_ROOT_FD` for details as to why this exists\n        if fd == VIRTUAL_ROOT_FD {\n            ctx.data().state.fs.root_fs.remove_dir(Path::new(path))?;\n        } else {\n            let base_dir = ctx.data().state.fs.get_fd(fd).map_err(|err| {\n                anyhow::format_err!(\n                    \"journal restore error: invalid directory descriptor (fd={fd}) - {err}\"\n                )\n            })?;\n            if let Err(err) =\n                crate::syscalls::path_remove_directory_internal(ctx, fd, base_dir, path)\n            {\n                bail!(\"journal restore error: failed to remove directory - {err}\");\n            }\n        }\n        Ok(())\n    }\n}\n","sourceCodeStart":23,"sourceCodeEnd":47,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/wasix/src/journal/effector/syscalls/path_remove_directory.rs#L23-L47","documentation":"apply_path_remove_directory replays a PathRemoveDirectory entry by calling path_remove_directory_internal; any error propagates into this bail. The directory removal recorded in the journal could not be reproduced, so the restored filesystem state would diverge from the snapshot and restore stops.","triggerScenarios":"Journal restore replaying PathRemoveDirectory when the target directory doesn't exist (Noent), is not empty (Notempty), the fd is invalid, or the filesystem lacks permission for removal.","commonSituations":"Restoring into a fresh/already-cleaned filesystem where the directory is already gone; a directory recreated or populated by other restore steps (Notempty); read-only or capability-restricted mounts.","solutions":["Make the restore environment's filesystem state match the snapshot state at capture time (recreate expected contents).","Grant write/remove rights to the relevant preopen directory.","Ensure journals replay in order so prior entries (files created inside the dir) are applied first.","Retake the snapshot from an environment consistent with the restore target."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check that the recorded removals are still reproducible\nfor op in journal.remove_directory_entries() {\n    let p = env.resolve_preopen_path(op.fd, &op.path)\n        .ok_or_else(|| anyhow::anyhow!(\"invalid dir fd {} for restore\", op.fd))?;\n    // dir must exist and be removable at replay time\n    if !std::path::Path::new(&p).is_dir() {\n        return Err(anyhow::anyhow!(\"directory '{}' missing; replay state diverged\", p));\n    }\n}","typeGuard":"fn is_removable_dir(p: &std::path::Path) -> bool {\n    std::fs::read_dir(p).map(|mut d| d.next().is_none()).unwrap_or(false)\n}","tryCatchPattern":"match restore_from_journal(&env, &journal) {\n    Err(e) if e.to_string().contains(\"failed to remove directory\") => {\n        eprintln!(\"dir removal replay failed: {e}; check journal order and fs state\");\n        resume_with_fresh_snapshot()?;\n    }\n    other => other?,\n}","preventionTips":["Replay journals in order so prior creations inside the directory are applied first.","Grant write/remove rights on the target preopen mount.","Start restore from a filesystem state matching the snapshot's."],"tags":["wasix","journal","path-remove-directory","filesystem","snapshot-restore"],"backgroundTag":"journal-restore-failed","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}