{"record":{"id":"95131776bdde668b","repo":"ruvnet/RuView","slug":"failed-to-create-data-dir-e","errorCode":null,"errorMessage":"failed to create data_dir {}: {e}","messagePattern":"failed to create data_dir (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"v2/crates/wifi-densepose-pointcloud/src/training.rs","lineNumber":167,"sourceCode":"            near_clip: 0.3,\n            far_clip: 8.0,\n            gamma: 1.0,\n            samples_used: 0,\n            rmse: f32::MAX,\n        }\n    }\n}\n\nimpl TrainingSession {\n    /// Create a new training session rooted at `data_dir`.\n    ///\n    /// `data_dir` must not contain `..` components — we reject path traversal\n    /// attempts from CLI/API input. The directory is created if missing and\n    /// then canonicalised so every subsequent write stays inside it.\n    pub fn new(data_dir: &str) -> Result<Self> {\n        let path = sanitize_data_path(data_dir)?;\n        std::fs::create_dir_all(&path)\n            .map_err(|e| anyhow!(\"failed to create data_dir {}: {e}\", path.display()))?;\n        // Canonicalise so path-traversal checks in safe_join have a fixed root.\n        let path = path\n            .canonicalize()\n            .map_err(|e| anyhow!(\"cannot canonicalise data_dir {}: {e}\", path.display()))?;\n\n        // Load existing calibration if available\n        let cal_path = safe_join(&path, \"calibration.json\")\n            // safe_join needs the parent to exist; for initial load that's always data_dir\n            .or_else(|_| Ok::<_, anyhow::Error>(path.join(\"calibration.json\")))?;\n        let calibration = if cal_path.exists() {\n            let data = std::fs::read_to_string(&cal_path)?;\n            serde_json::from_str(&data).unwrap_or_default()\n        } else {\n            DepthCalibration::default()\n        };\n\n        Ok(Self {\n            samples: Vec::new(),","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/v2/crates/wifi-densepose-pointcloud/src/training.rs#L149-L185","documentation":"`TrainingSession::new` runs `std::fs::create_dir_all` on the sanitized data dir. Any mkdir failure is reported with the target path: a path component already exists as a regular file, EACCES when the user cannot write an ancestor, or EROFS on a read-only filesystem. Sanitization has already passed at this point, so the cause is environmental, not traversal.","triggerScenarios":"`runs.json` exists as a file and `runs.json/sub` is requested; unprivileged user targeting `/var/lib/ruview`; a read-only rootfs or ro-mounted USB stick at the target; SELinux denying dir creation.","commonSituations":"Embedded or container images with read-only rootfs and no writable volume; stale files occupying the intended directory name; wrong HOME when running under a service manager.","solutions":["Remove or rename the regular file blocking the path (`rm runs`) and retry.","Choose a writable location (e.g. under `$HOME` or a mounted volume) or grant write permission on the ancestor / remount rw.","Diagnose per-component with `namei -l <path>` to find where access stops."],"exampleFix":"# before\nruview-train --data-dir /mnt/usb/runs     # read-only mount -> failed to create data_dir\n# after\nmount -o remount,rw /mnt/usb || ruview-train --data-dir /home/op/runs","handlingStrategy":"validation","validationCode":"fn data_dir_creatable(raw: &str) -> bool {\n    let p = std::path::Path::new(raw);\n    // no component may already exist as a non-directory\n    let mut cur = std::path::PathBuf::new();\n    for c in p.components() {\n        cur.push(c);\n        if cur.exists() && !cur.is_dir() {\n            return false;\n        }\n    }\n    true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pre-create the data dir in provisioning (`mkdir -p`) so the API never has to.","Avoid read-only mounts and system paths for data_dir; prefer $HOME or a mounted volume.","Use `namei -l <path>` when creation fails to find the blocking component."],"tags":["rust","filesystem","io","permissions","training"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}